@mx-cartographer/experiences 9.6.12 → 9.6.14-alpha-ram1-bill-amount-not-std

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 (78) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/common/components/CurrencyDialog.d.ts +6 -1
  3. package/dist/common/components/CurrencyDialog.es.js +24 -23
  4. package/dist/common/components/CurrencyDialog.es.js.map +1 -1
  5. package/dist/core/types/Insights.d.ts +7 -1
  6. package/dist/core/types/Insights.es.js.map +1 -1
  7. package/dist/core/types/InsightsInstanceSlotData.d.ts +5 -1
  8. package/dist/core/types/InsightsInstanceSlotData.es.js.map +1 -1
  9. package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js +3 -3
  10. package/dist/insights-v2/actionBlocks/AmountInputModalBlock/AmountInputModalBlock.es.js +66 -61
  11. package/dist/insights-v2/actionBlocks/AmountInputModalBlock/AmountInputModalBlock.es.js.map +1 -1
  12. package/dist/insights-v2/actionBlocks/ConnectWidgetActionBlock.es.js +17 -11
  13. package/dist/insights-v2/actionBlocks/ConnectWidgetActionBlock.es.js.map +1 -1
  14. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/layout.d.ts +27 -0
  15. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/layout.es.js +14 -0
  16. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/layout.es.js.map +1 -0
  17. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js +5 -5
  18. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js.map +1 -1
  19. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/util.d.ts +6 -2
  20. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/util.es.js +7 -4
  21. package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/util.es.js.map +1 -1
  22. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/TransactionHistoryBlock.es.js +72 -66
  23. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/TransactionHistoryBlock.es.js.map +1 -1
  24. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/useTransactionHistory.d.ts +1 -3
  25. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/useTransactionHistory.es.js +14 -13
  26. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/useTransactionHistory.es.js.map +1 -1
  27. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/utils.d.ts +8 -2
  28. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/utils.es.js +48 -27
  29. package/dist/insights-v2/actionBlocks/TransactionHistoryBlock/utils.es.js.map +1 -1
  30. package/dist/insights-v2/actionBlocks/util.d.ts +4 -3
  31. package/dist/insights-v2/actionBlocks/util.es.js.map +1 -1
  32. package/dist/insights-v2/analytics/analyticsEventsConfig.d.ts +67 -0
  33. package/dist/insights-v2/analytics/analyticsEventsConfig.es.js +59 -0
  34. package/dist/insights-v2/analytics/analyticsEventsConfig.es.js.map +1 -0
  35. package/dist/insights-v2/analytics/index.d.ts +3 -0
  36. package/dist/insights-v2/analytics/resolveAnalyticsEvent.d.ts +5 -0
  37. package/dist/insights-v2/analytics/resolveAnalyticsEvent.es.js +19 -0
  38. package/dist/insights-v2/analytics/resolveAnalyticsEvent.es.js.map +1 -0
  39. package/dist/insights-v2/analytics/useAnalyticsEvent.d.ts +3 -0
  40. package/dist/insights-v2/analytics/useAnalyticsEvent.es.js +20 -0
  41. package/dist/insights-v2/analytics/useAnalyticsEvent.es.js.map +1 -0
  42. package/dist/insights-v2/beatActions.d.ts +18 -13
  43. package/dist/insights-v2/beatActions.es.js.map +1 -1
  44. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.d.ts +7 -3
  45. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js +30 -30
  46. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js.map +1 -1
  47. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/utils.d.ts +1 -2
  48. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/utils.es.js +13 -13
  49. package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/utils.es.js.map +1 -1
  50. package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.d.ts +4 -1
  51. package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.es.js.map +1 -1
  52. package/dist/insights-v2/components/BaseLayout.es.js +89 -79
  53. package/dist/insights-v2/components/BaseLayout.es.js.map +1 -1
  54. package/dist/insights-v2/components/CompactInsightCard.d.ts +6 -3
  55. package/dist/insights-v2/components/CompactInsightCard.es.js +83 -56
  56. package/dist/insights-v2/components/CompactInsightCard.es.js.map +1 -1
  57. package/dist/insights-v2/components/LogoFromGuid.d.ts +2 -2
  58. package/dist/insights-v2/components/LogoFromGuid.es.js +44 -32
  59. package/dist/insights-v2/components/LogoFromGuid.es.js.map +1 -1
  60. package/dist/insights-v2/components/SubHeader.es.js +3 -2
  61. package/dist/insights-v2/components/SubHeader.es.js.map +1 -1
  62. package/dist/insights-v2/components/chartblocks/EmptyBarChart.es.js +4 -4
  63. package/dist/insights-v2/components/shared/EntityLogo.es.js +31 -21
  64. package/dist/insights-v2/components/shared/EntityLogo.es.js.map +1 -1
  65. package/dist/insights-v2/components/shared/images/FeeDetected.es.js +243 -0
  66. package/dist/insights-v2/components/shared/images/FeeDetected.es.js.map +1 -0
  67. package/dist/insights-v2/ctaActions/ctaHandlers.d.ts +1 -6
  68. package/dist/insights-v2/ctaActions/ctaHandlers.es.js.map +1 -1
  69. package/dist/insights-v2/ctaActions/index.d.ts +1 -1
  70. package/dist/insights-v2/ctaActions/runCtaAction.d.ts +20 -5
  71. package/dist/insights-v2/ctaActions/runCtaAction.es.js +63 -41
  72. package/dist/insights-v2/ctaActions/runCtaAction.es.js.map +1 -1
  73. package/dist/insights-v2/ctaActions/types.d.ts +6 -5
  74. package/dist/insights-v2/index.es.js +99 -99
  75. package/dist/insights-v2/mappings/blocks.es.js +2 -2
  76. package/dist/transactions/components/shared/TransactionDetails.es.js +161 -152
  77. package/dist/transactions/components/shared/TransactionDetails.es.js.map +1 -1
  78. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## [9.6.15] - 10-16-2026
2
+
3
+ - **CHANGED** - `BarchartBlock` and the transaction-history drawer read only the Insights 2.0 slot contract, `instance_slot.data` typed as `BarChartBlockData` (`series` as the `data_series` column, `category_guid`, `average_amount`, `ariaLabel`, `additional_data` as the legend rows: `[0]` monthly amount, `[1]` trend), with no `instance_slot_data`. The drawer maps it through `toDrillDownSlotData` (beat transactions are the series' rows). `average_amount` / `ariaLabel` live on `BarChartBlockData` only. Bill Amount Not Standard is the first beat sending it (WEC-1834)
4
+ - **CHANGED** - The transaction-history drawer's sub-heading and tip read the Insights 2.0 envelope (`subtitle` as the text, the header `logo.guid` as the merchant logo) through `resolveDrillDownSubHeader` (WEC-1834)
5
+ - **ADDED** - `CompactInsightCard` draws its single action from `primary_cta ?? in_description_cta` and hands either to `onCtaClick`: embedded cards word their link as `in_description_cta` (the convention mini and micro already follow). In `TransactionDetails`, a v2 action naming `transaction_history_block` opens the existing drill-down drawer, its bars built from the embedded envelope's `instance_slot.data.series` (WEC-1834)
6
+ - **ADDED** - `category_color` visual in `CompactInsightCard`'s `InsightVisual`: the embedded card draws a `TinyBarChart` of the latest three bars, tinted by the slot's `category_guid`, in place of the logo tile (Figma 222:33404 / 226:33768), with `BillAmountHigher` / `BillAmountLower` stories. The Bill Amount Not Standard bar-chart mock now carries tupac's generated full envelope (WEC-1834)
7
+
8
+ ## [9.6.14] - 10-15-2026
9
+
10
+ - **ADDED** - `onAnalyticsEvent` callback on `BeatActions` (WEC-1849)
11
+ - **ADDED** - `src/insights-v2/analytics/` module: events config, resolver, `useAnalyticsEvent()` hook (WEC-1849)
12
+ - **ADDED** - analytics routed through ctaActions via `sendCtaAnalytics` (WEC-1849)
13
+ - **ADDED** - `PRIMARY_ACTION_SELECTED` / `SECONDARY_ACTION_SELECTED` / `FIRST_TIME_PRIMARY_ACTION_SELECTED` CTA press events (WEC-1849)
14
+ - **ADDED** - `CHART_BAR_CLICKED` / `DRAWER_CHART_BAR_CLICKED` / `TAB_SELECTED` chart analytics events (WEC-1849)
15
+ - **ADDED** - Declarative analytics trigger: `analytics` on `RunHandlerOptions` (WEC-1849)
16
+ - **ADDED** - LowAccountBalance + SavingsOpportunityV2 dialog analytics in `AmountInputModalBlock` (WEC-1849)
17
+ - **ADDED** - `OPENED_CONNECT_DRAWER` event in `ConnectWidgetActionBlock` (WEC-1849)
18
+ - **NOTE** - Scoped to Firefly analytics only (WEC-1849)
19
+ - **REFACTOR** - Collapsed the `sendCtaAnalytics` → fake-CTA → `ctaHandlers.sendAnalyticsEvent` chain into one function that resolves the payload and calls `onAnalyticsEvent` directly; removed the now-redundant runtime eventKey check (a typo'd key already fails typecheck). Kept `CtaStep.analytics` and the runner's `step.analytics` check for future `ctaConfig` entries (none use it yet; `RunHandlerOptions.analytics` has real callers today). Removed the `AnalyticsEvents` self-mapping constant — `sendCtaAnalytics`/`resolveAnalyticsEvent`/`useAnalyticsEvent()`/`RunHandlerOptions.analytics` now take the catalogue entry itself (e.g. `ANALYTICS_EVENTS_CONFIG.PRIMARY_ACTION_SELECTED`) instead of a lookup key, so there is nothing to look up and a typo'd property name fails typecheck at the call site. Dropped the unused `stores` parameter from `resolveAnalyticsEvent`/`postHog.properties`. Added `reportCtaClick` (press event + first-time bookkeeping together) and routed the `contact_support_block` bypass through it, so that CTA now also fires `FIRST_TIME_PRIMARY_ACTION_SELECTED` and records `cta_clicked_at` on its first press (WEC-1849)
20
+
21
+ ## [9.6.13] - 10-15-2026
22
+
23
+ - **ADDED** - `ICO-<name>` logo guids: `logoFromEntityGuid` / `logoFromRef` map them to a filled mx-icons status icon in the logo's `color`, `LogoFromGuid` draws it and `isLogoGuid` accepts the prefix; `SubHeader` draws `logo_fill` icons filled. Fee Detected's header sends `ICO-error` (WEC-1885)
24
+ - **ADDED** - `TransactionDetailsBlock` resolves its drawer bottom actions from a per-variant `layout.ts` config keyed by the CTA's `variant` (extensible per variant); `merchant_budget` shows the "Add a Merchant Budget" row and `no_merchant_budget` drops it (null/unknown variants fall back to showing it). Variants name the drilldown behavior rather than a beat, so any CTA can reuse them; the Fee Detected mocks send `merchant_budget` (Has Merchant) / `no_merchant_budget` (No Merchant) with a null secondary CTA block. Replaces the earlier `drilldown_data.hide_merchant_budget_option` flag, which has been removed from `DrilldownData` (WEC-1885)
25
+ - **ADDED** - `with_illustration` visual in `CompactInsightCard`'s `InsightVisual`, drawing a single theme-aware `FeeDetected.svg` (its `brand300` elements recolored per theme by `ThemedSVGImage`, so no separate dark asset), with a `WithIllustration` story (WEC-1885)
26
+ - **ADDED** - `TransactionDetailsBlock` resolves its bottom actions from the description link when that link opened the drawer (`getBottomActionsByVariant` takes `in_description_cta`), so a link sending `no_merchant_budget` (LargeTransactionV2 mini "View Details") drops the "Add a Merchant Budget" row. `UnifiedDepositMini` story uses the mini envelope (WEC-1885)
27
+ - **CHANGED** - `SecondaryCTA.block` widened to `string | null`: the backend sends `null` when the secondary CTA opens no drawer (e.g. Fee Detected "Contact Support"), which the Fee Detected mocks now mirror (WEC-1885)
28
+
1
29
  ## [9.6.12] - 10-15-2026
2
30
 
3
31
  - **ADDED** - `account_block` reads the Insights 2.0 slot contract (`instance_slot.data`) for a new variant, falling back to the flat legacy fields: `low_balance` (the existing red tile, its institution logo badged per the layout's new `badge` field; no amount is drawn when the slot sends none). A new `statusIconName` helper maps `ICO-<name>` to an mx-icons name and rejects anything else. `low_balance` shares `low_balance_alert`'s layout entry (WEC-1903)
@@ -12,6 +12,11 @@ interface CurrencyDialogProps {
12
12
  /** Disables the primary button on top of the built-in input check (e.g. while saving). */
13
13
  isPrimaryDisabled?: boolean;
14
14
  handleInputChange?: (value: string) => void;
15
+ /**
16
+ * Click on the amount input (e.g. analytics). Click, not focus: the input autofocuses on open,
17
+ * so a focus callback would fire per open rather than per user interaction.
18
+ */
19
+ handleInputClick?: () => void;
15
20
  handleModalClose: () => void;
16
21
  handlePrimaryAction: () => void;
17
22
  handleSecondaryAction?: () => void;
@@ -23,5 +28,5 @@ interface CurrencyDialogProps {
23
28
  subtitle?: ReactNode;
24
29
  title: string;
25
30
  }
26
- declare const CurrencyDialog: ({ closeAriaLabel, content, errorText, inputLabel, inputValue, isOpen, isPrimaryDisabled, handleInputChange, handleModalClose, handlePrimaryAction, handleSecondaryAction, primaryColor, primaryText, secondaryColor, secondaryText, subtitle, title, }: CurrencyDialogProps) => import("react/jsx-runtime").JSX.Element;
31
+ declare const CurrencyDialog: ({ closeAriaLabel, content, errorText, inputLabel, inputValue, isOpen, isPrimaryDisabled, handleInputChange, handleInputClick, handleModalClose, handlePrimaryAction, handleSecondaryAction, primaryColor, primaryText, secondaryColor, secondaryText, subtitle, title, }: CurrencyDialogProps) => import("react/jsx-runtime").JSX.Element;
27
32
  export default CurrencyDialog;
@@ -1,18 +1,18 @@
1
- import { useScreenSize as k } from "../hooks/useScreenSize.es.js";
1
+ import { useScreenSize as S } from "../hooks/useScreenSize.es.js";
2
2
  import n from "@mui/material/Stack";
3
- import { H3 as S, P as j } from "@mxenabled/mxui";
3
+ import { H3 as j, P as M } from "@mxenabled/mxui";
4
4
  import f from "@mui/material/Button";
5
- import { Icon as M } from "@mxenabled/mx-icons";
5
+ import { Icon as $ } from "@mxenabled/mx-icons";
6
6
  import { jsx as o, jsxs as t } from "react/jsx-runtime";
7
- import $ from "@mui/material/Dialog";
8
- import B from "@mui/material/DialogContent";
9
- import F from "@mui/material/IconButton";
10
- import H from "@mui/material/DialogActions";
11
- import w from "@mui/material/InputAdornment";
12
- import A from "@mui/material/TextField";
13
- var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValue: i, isOpen: u, isPrimaryDisabled: x = !1, handleInputChange: b, handleModalClose: m, handlePrimaryAction: s, handleSecondaryAction: C, primaryColor: D = "primary", primaryText: p, secondaryColor: v = "primary", secondaryText: l, subtitle: y, title: c }) => {
14
- const d = x || (r ? !(i !== "" && i !== "0" && !isNaN(parseFloat(i ?? "0"))) : !1), { isSmallMobile: I } = k();
15
- return /* @__PURE__ */ o($, {
7
+ import B from "@mui/material/Dialog";
8
+ import F from "@mui/material/DialogContent";
9
+ import H from "@mui/material/IconButton";
10
+ import w from "@mui/material/DialogActions";
11
+ import A from "@mui/material/InputAdornment";
12
+ import N from "@mui/material/TextField";
13
+ var X = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValue: i, isOpen: u, isPrimaryDisabled: x = !1, handleInputChange: b, handleInputClick: C, handleModalClose: m, handlePrimaryAction: s, handleSecondaryAction: D, primaryColor: k = "primary", primaryText: p, secondaryColor: v = "primary", secondaryText: l, subtitle: y, title: c }) => {
14
+ const d = x || (r ? !(i !== "" && i !== "0" && !isNaN(parseFloat(i ?? "0"))) : !1), { isSmallMobile: I } = S();
15
+ return /* @__PURE__ */ o(B, {
16
16
  "aria-label": c,
17
17
  "aria-labelledby": "modal-title",
18
18
  maxWidth: "xs",
@@ -23,7 +23,7 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
23
23
  "& .MuiDialogContent-root": { p: 0 },
24
24
  ...I && { "& .MuiDialog-paper": { minWidth: "100%" } }
25
25
  },
26
- children: /* @__PURE__ */ o(B, { children: /* @__PURE__ */ t("form", {
26
+ children: /* @__PURE__ */ o(F, { children: /* @__PURE__ */ t("form", {
27
27
  onSubmit: (e) => {
28
28
  e.preventDefault(), d || s();
29
29
  },
@@ -41,11 +41,11 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
41
41
  },
42
42
  children: [/* @__PURE__ */ t(n, {
43
43
  sx: { gap: 4 },
44
- children: [/* @__PURE__ */ o(S, {
44
+ children: [/* @__PURE__ */ o(j, {
45
45
  id: "modal-title",
46
46
  children: c
47
47
  }), y]
48
- }), /* @__PURE__ */ o(F, {
48
+ }), /* @__PURE__ */ o(H, {
49
49
  "aria-label": h,
50
50
  onClick: m,
51
51
  sx: {
@@ -54,7 +54,7 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
54
54
  right: 8,
55
55
  top: 18
56
56
  },
57
- children: /* @__PURE__ */ o(M, {
57
+ children: /* @__PURE__ */ o($, {
58
58
  name: "close",
59
59
  sx: { color: "action.active" }
60
60
  })
@@ -65,10 +65,10 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
65
65
  gap: 24,
66
66
  px: 24
67
67
  },
68
- children: [/* @__PURE__ */ o(j, {
68
+ children: [/* @__PURE__ */ o(M, {
69
69
  variant: "subtitle1",
70
70
  children: g
71
- }), r && /* @__PURE__ */ o(A, {
71
+ }), r && /* @__PURE__ */ o(N, {
72
72
  autoFocus: !0,
73
73
  error: !!a,
74
74
  helperText: a,
@@ -77,8 +77,9 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
77
77
  onChange: ({ target: { value: e } }) => {
78
78
  /^\d*\.?\d*$/.test(e) && b?.(e);
79
79
  },
80
+ onClick: C,
80
81
  slotProps: {
81
- input: { startAdornment: /* @__PURE__ */ o(w, {
82
+ input: { startAdornment: /* @__PURE__ */ o(A, {
82
83
  position: "start",
83
84
  children: "$"
84
85
  }) },
@@ -93,7 +94,7 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
93
94
  value: i
94
95
  })]
95
96
  }),
96
- /* @__PURE__ */ t(H, {
97
+ /* @__PURE__ */ t(w, {
97
98
  sx: {
98
99
  justifyContent: "flex-end",
99
100
  gap: 16,
@@ -103,11 +104,11 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
103
104
  children: [l && /* @__PURE__ */ o(f, {
104
105
  "aria-label": l,
105
106
  color: v,
106
- onClick: C,
107
+ onClick: D,
107
108
  children: l
108
109
  }), /* @__PURE__ */ o(f, {
109
110
  "aria-label": p,
110
- color: D,
111
+ color: k,
111
112
  disabled: d,
112
113
  onClick: s,
113
114
  variant: "contained",
@@ -119,7 +120,7 @@ var U = ({ closeAriaLabel: h, content: g, errorText: a, inputLabel: r, inputValu
119
120
  });
120
121
  };
121
122
  export {
122
- U as default
123
+ X as default
123
124
  };
124
125
 
125
126
  //# sourceMappingURL=CurrencyDialog.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CurrencyDialog.es.js","names":[],"sources":["../../../src/common/components/CurrencyDialog.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\n\nimport { Icon } from '@mxenabled/mx-icons'\nimport { H3, P } from '@mxenabled/mxui'\n\nimport Button, { type ButtonProps } from '@mui/material/Button'\nimport Dialog from '@mui/material/Dialog'\nimport DialogActions from '@mui/material/DialogActions'\nimport DialogContent from '@mui/material/DialogContent'\nimport IconButton from '@mui/material/IconButton'\nimport InputAdornment from '@mui/material/InputAdornment'\nimport Stack from '@mui/material/Stack'\nimport TextField from '@mui/material/TextField'\n\nimport { useScreenSize } from '../hooks'\n\ninterface CurrencyDialogProps {\n closeAriaLabel: string\n /** Body copy; a node so callers can emphasise part of it (e.g. a bold account name). */\n content?: ReactNode\n /** Validation or save error, shown under the input and marking it invalid. */\n errorText?: string\n inputLabel?: string\n inputValue?: string\n isOpen: boolean\n /** Disables the primary button on top of the built-in input check (e.g. while saving). */\n isPrimaryDisabled?: boolean\n handleInputChange?: (value: string) => void\n handleModalClose: () => void\n handlePrimaryAction: () => void\n handleSecondaryAction?: () => void\n primaryColor?: ButtonProps['color']\n primaryText: string\n secondaryColor?: ButtonProps['color']\n secondaryText?: string\n /** A line under the title, e.g. the account a setting applies to. */\n subtitle?: ReactNode\n title: string\n}\n\n// Created for V2 of BudgetDetailsDrawer.\n// The previous design will be replaced once the new design is finalized.\n// Also needs to be updated to use the mxui library\n// with the updated Dialog components.\n\nconst CurrencyDialog = ({\n closeAriaLabel,\n content,\n errorText,\n inputLabel,\n inputValue,\n isOpen,\n isPrimaryDisabled = false,\n handleInputChange,\n handleModalClose,\n handlePrimaryAction,\n handleSecondaryAction,\n primaryColor = 'primary',\n primaryText,\n secondaryColor = 'primary',\n secondaryText,\n subtitle,\n title,\n}: CurrencyDialogProps) => {\n const numericValue = parseFloat(inputValue ?? '0')\n const isValid = inputValue !== '' && inputValue !== '0' && !isNaN(numericValue)\n // One rule for the button and for Enter: the form's submit must not bypass a disabled button.\n const isPrimaryBlocked = isPrimaryDisabled || (inputLabel ? !isValid : false)\n\n const { isSmallMobile } = useScreenSize()\n\n return (\n <Dialog\n aria-label={title}\n aria-labelledby=\"modal-title\"\n maxWidth=\"xs\"\n onClose={handleModalClose}\n open={isOpen}\n role=\"dialog\"\n sx={{\n '& .MuiDialogContent-root': { p: 0 },\n ...(isSmallMobile && { '& .MuiDialog-paper': { minWidth: '100%' } }),\n }}\n >\n <DialogContent>\n <form\n onSubmit={(e) => {\n e.preventDefault()\n if (!isPrimaryBlocked) handlePrimaryAction()\n }}\n >\n <Stack\n sx={{\n alignItems: 'center',\n flexDirection: 'row',\n justifyContent: 'space-between',\n pb: 12,\n pl: 24,\n position: 'relative',\n pr: 16,\n pt: 24,\n }}\n >\n <Stack sx={{ gap: 4 }}>\n <H3 id=\"modal-title\">{title}</H3>\n {subtitle}\n </Stack>\n <IconButton\n aria-label={closeAriaLabel}\n onClick={handleModalClose}\n sx={{ minHeight: 24, position: 'absolute', right: 8, top: 18 }}\n >\n <Icon name=\"close\" sx={{ color: 'action.active' }} />\n </IconButton>\n </Stack>\n <Stack sx={{ gap: 24, px: 24 }}>\n <P variant=\"subtitle1\">{content}</P>\n {inputLabel && (\n <TextField\n autoFocus={true}\n error={!!errorText}\n helperText={errorText}\n inputMode=\"decimal\"\n label={inputLabel}\n onChange={({ target: { value } }) => {\n if (!/^\\d*\\.?\\d*$/.test(value)) return\n\n handleInputChange?.(value)\n }}\n slotProps={{\n input: {\n startAdornment: <InputAdornment position=\"start\">$</InputAdornment>,\n },\n // Announce errors: focus is usually on the primary button when one appears.\n formHelperText: { role: 'alert' },\n htmlInput: {\n 'aria-label': inputLabel,\n noValidate: true,\n pattern: '[0-9]*\\\\.?[0-9]*',\n },\n }}\n type=\"text\"\n value={inputValue}\n />\n )}\n </Stack>\n <DialogActions\n sx={{\n justifyContent: 'flex-end',\n gap: 16,\n p: 24,\n '>:not(style)~:not(style)': { ml: 0 },\n }}\n >\n {secondaryText && (\n <Button\n aria-label={secondaryText}\n color={secondaryColor}\n onClick={handleSecondaryAction}\n >\n {secondaryText}\n </Button>\n )}\n <Button\n aria-label={primaryText}\n color={primaryColor}\n disabled={isPrimaryBlocked}\n onClick={handlePrimaryAction}\n variant=\"contained\"\n >\n {primaryText}\n </Button>\n </DialogActions>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nexport default CurrencyDialog\n"],"mappings":"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"}
1
+ {"version":3,"file":"CurrencyDialog.es.js","names":[],"sources":["../../../src/common/components/CurrencyDialog.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\n\nimport { Icon } from '@mxenabled/mx-icons'\nimport { H3, P } from '@mxenabled/mxui'\n\nimport Button, { type ButtonProps } from '@mui/material/Button'\nimport Dialog from '@mui/material/Dialog'\nimport DialogActions from '@mui/material/DialogActions'\nimport DialogContent from '@mui/material/DialogContent'\nimport IconButton from '@mui/material/IconButton'\nimport InputAdornment from '@mui/material/InputAdornment'\nimport Stack from '@mui/material/Stack'\nimport TextField from '@mui/material/TextField'\n\nimport { useScreenSize } from '../hooks'\n\ninterface CurrencyDialogProps {\n closeAriaLabel: string\n /** Body copy; a node so callers can emphasise part of it (e.g. a bold account name). */\n content?: ReactNode\n /** Validation or save error, shown under the input and marking it invalid. */\n errorText?: string\n inputLabel?: string\n inputValue?: string\n isOpen: boolean\n /** Disables the primary button on top of the built-in input check (e.g. while saving). */\n isPrimaryDisabled?: boolean\n handleInputChange?: (value: string) => void\n /**\n * Click on the amount input (e.g. analytics). Click, not focus: the input autofocuses on open,\n * so a focus callback would fire per open rather than per user interaction.\n */\n handleInputClick?: () => void\n handleModalClose: () => void\n handlePrimaryAction: () => void\n handleSecondaryAction?: () => void\n primaryColor?: ButtonProps['color']\n primaryText: string\n secondaryColor?: ButtonProps['color']\n secondaryText?: string\n /** A line under the title, e.g. the account a setting applies to. */\n subtitle?: ReactNode\n title: string\n}\n\n// Created for V2 of BudgetDetailsDrawer.\n// The previous design will be replaced once the new design is finalized.\n// Also needs to be updated to use the mxui library\n// with the updated Dialog components.\n\nconst CurrencyDialog = ({\n closeAriaLabel,\n content,\n errorText,\n inputLabel,\n inputValue,\n isOpen,\n isPrimaryDisabled = false,\n handleInputChange,\n handleInputClick,\n handleModalClose,\n handlePrimaryAction,\n handleSecondaryAction,\n primaryColor = 'primary',\n primaryText,\n secondaryColor = 'primary',\n secondaryText,\n subtitle,\n title,\n}: CurrencyDialogProps) => {\n const numericValue = parseFloat(inputValue ?? '0')\n const isValid = inputValue !== '' && inputValue !== '0' && !isNaN(numericValue)\n // One rule for the button and for Enter: the form's submit must not bypass a disabled button.\n const isPrimaryBlocked = isPrimaryDisabled || (inputLabel ? !isValid : false)\n\n const { isSmallMobile } = useScreenSize()\n\n return (\n <Dialog\n aria-label={title}\n aria-labelledby=\"modal-title\"\n maxWidth=\"xs\"\n onClose={handleModalClose}\n open={isOpen}\n role=\"dialog\"\n sx={{\n '& .MuiDialogContent-root': { p: 0 },\n ...(isSmallMobile && { '& .MuiDialog-paper': { minWidth: '100%' } }),\n }}\n >\n <DialogContent>\n <form\n onSubmit={(e) => {\n e.preventDefault()\n if (!isPrimaryBlocked) handlePrimaryAction()\n }}\n >\n <Stack\n sx={{\n alignItems: 'center',\n flexDirection: 'row',\n justifyContent: 'space-between',\n pb: 12,\n pl: 24,\n position: 'relative',\n pr: 16,\n pt: 24,\n }}\n >\n <Stack sx={{ gap: 4 }}>\n <H3 id=\"modal-title\">{title}</H3>\n {subtitle}\n </Stack>\n <IconButton\n aria-label={closeAriaLabel}\n onClick={handleModalClose}\n sx={{ minHeight: 24, position: 'absolute', right: 8, top: 18 }}\n >\n <Icon name=\"close\" sx={{ color: 'action.active' }} />\n </IconButton>\n </Stack>\n <Stack sx={{ gap: 24, px: 24 }}>\n <P variant=\"subtitle1\">{content}</P>\n {inputLabel && (\n <TextField\n autoFocus={true}\n error={!!errorText}\n helperText={errorText}\n inputMode=\"decimal\"\n label={inputLabel}\n onChange={({ target: { value } }) => {\n if (!/^\\d*\\.?\\d*$/.test(value)) return\n\n handleInputChange?.(value)\n }}\n onClick={handleInputClick}\n slotProps={{\n input: {\n startAdornment: <InputAdornment position=\"start\">$</InputAdornment>,\n },\n // Announce errors: focus is usually on the primary button when one appears.\n formHelperText: { role: 'alert' },\n htmlInput: {\n 'aria-label': inputLabel,\n noValidate: true,\n pattern: '[0-9]*\\\\.?[0-9]*',\n },\n }}\n type=\"text\"\n value={inputValue}\n />\n )}\n </Stack>\n <DialogActions\n sx={{\n justifyContent: 'flex-end',\n gap: 16,\n p: 24,\n '>:not(style)~:not(style)': { ml: 0 },\n }}\n >\n {secondaryText && (\n <Button\n aria-label={secondaryText}\n color={secondaryColor}\n onClick={handleSecondaryAction}\n >\n {secondaryText}\n </Button>\n )}\n <Button\n aria-label={primaryText}\n color={primaryColor}\n disabled={isPrimaryBlocked}\n onClick={handlePrimaryAction}\n variant=\"contained\"\n >\n {primaryText}\n </Button>\n </DialogActions>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nexport default CurrencyDialog\n"],"mappings":"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"}
@@ -121,6 +121,8 @@ export interface Logo {
121
121
  institution_guid?: string;
122
122
  institution_name?: string;
123
123
  logo_color?: string;
124
+ /** Draw the `logo_name` icon filled (V2 `ICO-` logos). */
125
+ logo_fill?: boolean;
124
126
  logo_name?: string;
125
127
  merchant_guid?: string;
126
128
  merchant_name?: string;
@@ -196,7 +198,11 @@ export interface PrimaryCTA {
196
198
  }
197
199
  export interface SecondaryCTA {
198
200
  label: string;
199
- block: string;
201
+ /**
202
+ * Drawer block to open. `null` when the CTA opens nothing (ditto `secondary_cta_block: null`,
203
+ * e.g. Fee Detected's "Contact Support"): the press posts its message to the host instead.
204
+ */
205
+ block: string | null;
200
206
  variant?: string | null;
201
207
  /** See `PrimaryCTA.action_key` (ditto `secondary_cta_action`). */
202
208
  action_key?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"Insights.es.js","names":[],"sources":["../../../src/core/types/Insights.ts"],"sourcesContent":["// ============ Core InsightsV2 Types ============\n\nimport { InsightsInstanceSlotData } from './InsightsInstanceSlotData'\n\nexport interface ThemedSVGImageProps {\n divProps?: React.HTMLAttributes<HTMLDivElement>\n image: React.ComponentType<React.SVGProps<SVGSVGElement>>\n isMini?: boolean\n}\n\n/**\n * Emitted by a block when the user drills into a specific datum (e.g. clicks a\n * chart bar). Named fields rather than positional args so blocks with differing\n * shapes can extend this without the call sites transposing values.\n */\nexport interface DrilldownPayload {\n chartBarIndex: number\n tabIndex?: number\n transaction_guid?: string\n block?: string\n}\n\n/**\n * Which envelope a beat was fetched with. `embedded` (the transaction-row pill + details-drawer\n * card) and `notification` are V2 additions; a surface asks for one with `widget_type=` on the fetch.\n */\nexport type WidgetType = 'full' | 'mini' | 'micro' | 'embedded' | 'notification'\n\n/**\n * V2: the transaction-row tag, its own small section of the `embedded` envelope (the same grammar\n * as `description` / `footer`, with room for a tone or an icon later). Omitted for an insight that\n * tags no transaction row. It deliberately is *not* `short_title`, which stays a per-variant\n * attribute with a second consumer (the bank-holiday sub-header).\n */\nexport interface Pill {\n text: string\n}\n\n/**\n * V2: facts a drilldown shows that the card does not (e.g. the account number for the Transaction\n * Details drawer). A flat hash shared by every CTA of the card, omitted when the insight has none.\n * Never carries copy or user actions (memo, tags, hide, flag come from the transaction store).\n */\nexport type DrilldownData = Record<string, string | number | boolean | null>\n\nexport interface InsightsPayload {\n widget_type: WidgetType\n instance_slot: InstanceSlot\n /**\n * V1 only. The v2 contract carries everything a block needs on `instance_slot.data`,\n * and omits this key entirely (see the LargeTransactionV2 payload). Blocks that still require it\n * get it as a required field through `BlockProps`, which re-declares it.\n */\n instance_slot_data?: InsightsInstanceSlotData\n description: Description\n primary_cta?: PrimaryCTA\n secondary_cta?: SecondaryCTA\n title?: string\n sub_title?: Subtitle\n /**\n * V2 rename of `sub_title`: a flat string, with the logo promoted to the payload-level `logo`\n * field below. `sub_title` wins when both are present.\n */\n subtitle?: string\n /** V2: header logo paired with the flat `subtitle`: an entity guid or a status icon (`LogoRef`). */\n logo?: LogoRef\n /** V2: which design branch the backend picked (e.g. `no_merchant`). */\n variant?: string\n /** V2, `embedded` envelope only: the transaction-row pill. */\n pill?: Pill\n /** V2: drilldown-only facts, e.g. `{ account_number: 'XXXXXXXX043' }`. */\n drilldown_data?: DrilldownData\n footer?: Footer\n /**\n * V2: the link inside the description: on the full card a drawer of its own (Low Account\n * Balance's \"Transactions ›\"); on mini and micro the card's action, sent instead of `primary_cta`.\n * Absent when the beat has no link.\n */\n in_description_cta?: InDescriptionCTA\n guid: string\n user_guid: string\n client_guid?: string\n /** Template name, e.g. `LargeTransactionV2`. */\n template?: string\n revision?: number\n /** Unix seconds. */\n created_at?: number\n /** Unix seconds. */\n updated_at?: number\n /** Unix seconds. */\n active_at?: number\n displayed_at?: number | null\n dismissed_at: number | null\n cta_clicked_at?: number | null\n has_been_displayed?: boolean\n is_dismissed: boolean\n is_deleted?: boolean\n is_hidden_by_system?: boolean\n is_obsolete?: boolean\n is_refreshable?: boolean\n is_sampled?: boolean\n is_zero_state?: boolean\n status?: string | null\n /**\n * V2 (LargeTransactionV2 onward): the entities the beat is about, carried on the payload so\n * action blocks do not have to reach back out to the beat envelope.\n */\n primary_account_guid?: string | null\n primary_transaction_guid?: string | null\n primary_category_guid?: string | null\n primary_merchant_guid?: string | null\n /**\n * V2: the repeating transaction a subscription beat is about (Upcoming Subscription, Subscription\n * Price Increase). Read by `recurring_transaction_block`, see\n * `actionBlocks/RecurringTransactionBlock/subscriptionBeats.ts`.\n */\n primary_repeating_transaction_guid?: string | null\n}\n\nexport interface Legends {\n label: string\n value: number\n additional_value?: number\n additional_value_type?: string\n value_type?: string\n}\n\nexport interface Logo {\n category_guid?: string\n category_name?: string\n institution_guid?: string\n institution_name?: string\n logo_color?: string\n logo_name?: string\n merchant_guid?: string\n merchant_name?: string\n}\n\nexport interface Subtitle {\n logo?: Logo\n text: string\n}\n\n/**\n * A V2 logo, shared by the header (`InsightsPayload.logo`) and every instance-slot row. It takes\n * one of two shapes:\n *\n * - **Entity**: `guid`, whose prefix (`INS-` / `MCH-` / `CAT-`) picks the logo component, plus an\n * optional `fallback_guid` for when that component's asset cannot load. Today that is the\n * category behind an `MCH-` guid, which `MerchantLogo` shows as a tile when the merchant image\n * is missing.\n * - **Status icon**: `icon` (an mx-icons name, e.g. `warning`) and `color` (a theme palette path,\n * e.g. `error.main`), for subheaders that show a state rather than an entity (V1's\n * `logo_name` / `logo_color`).\n *\n * `alt` is the accessible name for either shape. A logo sends one shape; if it sends both, `icon`\n * wins, as `logo_name` does in V1's `SubHeader`.\n */\nexport interface LogoRef {\n alt?: string\n color?: string\n fallback_guid?: string\n guid?: string\n icon?: string\n}\n\nexport interface CategoryLogo {\n category_guid: string\n category_name: string\n}\n\nexport interface MerchantLogo {\n merchant_guid: string\n merchant_name: string\n}\n\nexport interface InstitutionLogo {\n institution_guid: string\n institution_name: string\n}\n\nexport interface Description {\n text: string\n html_text: string\n}\n\n/**\n * Post message a CTA press sends to the host, resolved by the backend for the beat's current\n * state. Absent/null = the backend has not described one: the frontend uses the template's\n * interim `ctaPostMessages` entry if there is one, else sends no message. `payload` carries only\n * beat-specific extras; the frontend always adds `beat_guid`, `beat_template`, `user_guid` and\n * `action_string`.\n */\nexport interface CtaPostMessageMetadata {\n /** Post message event; defaults to `beat/cta`. */\n event?: string | null\n /** Operation the host should perform, e.g. `op_1`, `op_2`, `op_3`. Defaults to `op_1`. */\n action?: string | null\n /** Beat-specific fields merged into the message metadata (account ids, amounts, ...). */\n payload?: Record<string, unknown> | null\n}\n\nexport interface PrimaryCTA {\n label: string\n block: string\n variant?: string | null\n /**\n * What pressing the CTA does beyond opening its block, named by the backend (ditto\n * `primary_cta_action`, passed through by tupac). Looked up in `insights-v2/ctaActions`;\n * null / absent / unknown means the CTA only opens its block or posts its message.\n */\n action_key?: string | null\n metadata?: CtaPostMessageMetadata | null\n}\n\nexport interface SecondaryCTA {\n label: string\n block: string\n variant?: string | null\n /** See `PrimaryCTA.action_key` (ditto `secondary_cta_action`). */\n action_key?: string | null\n metadata?: CtaPostMessageMetadata | null\n}\n\n/**\n * The description link: its label, the action block it opens and, like a CTA's, the variant that\n * tells that block what to show (ditto's `in_description_cta_variant`, e.g. `low_balance`). On mini\n * and micro it words the card's action; `block` is empty when that action opens no drawer.\n */\nexport interface InDescriptionCTA {\n label: string\n block?: string\n variant?: string | null\n action_key?: string | null\n}\n\nexport interface Footer {\n /** V1: a pre-formatted date string. */\n date?: string\n /**\n * The account label, on both V1 and V2. The backend resolves the plurality: one account sends\n * its name (e.g. `Epic Bank`), several send a localized count (e.g. `2 Accounts`), none sends\n * nothing. There is deliberately no separate `accounts` key — see tupac's `footer_account_label`.\n */\n account?: string\n /**\n * V2 (LargeTransactionV2 onward): unix seconds, formatted by `Footer` for display.\n * Replaces `date`; `date` wins when a beat somehow sends both.\n */\n timestamp?: number\n}\n\n// ============ Instance Slot Types ============\n// Values are the snake_case block names the backend sends on a beat's instance slot; the PascalCase\n// keys stay as friendly references (e.g. BlockType.BarChartBlock === 'bar_chart_block').\nexport const BlockType = {\n AccountBlock: 'account_block',\n AccountSwitchBlock: 'account_switch_block',\n BarChartBlock: 'bar_chart_block',\n BudgetBlock: 'budget_block',\n ImageBlock: 'image_block',\n TransactionBlock: 'transaction_block',\n DonutChartBlock: 'donut_chart_block',\n DoubleBarChartBlock: 'double_bar_chart_block',\n DoubleProgressBarBlock: 'double_progress_bar_block',\n DebtsBlock: 'debts_block',\n SaveExtraBlock: 'save_extra_block',\n SavingsOpportunityBlock: 'savings_opportunity_block',\n StepChartBlock: 'step_chart_block',\n SVGImageBlock: 'svg_image_block',\n UpcomingBillBlock: 'upcoming_bill_block',\n UpcomingSubscriptionBlock: 'upcoming_subscription_block',\n WithdrawalBlock: 'withdrawal_block',\n} as const\n\nexport type BlockType = (typeof BlockType)[keyof typeof BlockType]\n\n/**\n * A pre-localized row on a V2 instance slot. The backend resolves the copy and formatting; the\n * logo is a `LogoRef` (an entity guid or a status icon, see `logoFromRef`).\n */\nexport interface InstanceSlotRow {\n amount?: number\n logo?: LogoRef\n primary_text?: string\n secondary_text?: string\n}\n\n/**\n * V2: the slots a block's variant filled, keyed by slot name; ditto owns the names and omits any\n * slot it has no value for (`lib/ditto/blocks/<block>.yml`). Read with `slot()`, which names the\n * kind the caller expects.\n */\nexport interface InstanceSlotData {\n [slot: string]: unknown\n}\n\n/**\n * Reads one slot off a block's `data`; undefined when ditto did not fill it.\n *\n * The caller names the kind, because the slot's kind lives in the block's ditto schema and not\n * here — a block fills slots with whatever its card needs, so no fixed list of kinds would hold\n * (`account_switch_block` alone carries a boolean and `budget_block` a nested object).\n */\nexport const slot = <T = unknown>(\n data: InstanceSlotData | undefined,\n name: string,\n): T | undefined => data?.[name] as T | undefined\n\n/**\n * V2: which block renders this beat's content, and what it renders.\n *\n * `block` is optional: a beat whose template has no ditto config arrives as an empty `{}` and the\n * card renders its copy and CTAs alone, so a reader cannot assume a block is named. One interface\n * with `block` optional rather than a union with `Record<string, never>`, which TypeScript absorbs\n * — that union left `block` reading as required and typed a promise it did not keep.\n *\n * `variant` is optional for the same reason — the empty `{}` carries neither. Every ditto beat\n * file that names a block also names a variant, so a *filled* slot always has one; ditto drops a\n * nil variant rather than sending null, which is why the type is `string | null | undefined`.\n */\nexport interface InstanceSlot {\n block?: BlockType\n variant?: string | null\n /** The slots this block's variant declares in ditto. */\n data?: InstanceSlotData\n // Direct Deposit block (Set Up Direct Deposit, Switch Direct Deposit, Missing\n // Interest Rate): account facts carried flat on the slot, beside `data`.\n /** Primary line on the hero card, e.g. \"Epic Bank Checking, *1234\". */\n account_name?: string\n /** Secondary line beneath the name, e.g. \"Checking Account\" / \"Credit Card\". */\n account_type?: string\n /** Status pill label, e.g. \"Direct Deposit Not Set Up\" / \"Interest Rate: 19.99% APR\". */\n status_text?: string\n institution_guid?: string\n institution_name?: string\n // Shared across multiple V2 component blocks:\n // `amount` — UpcomingBillBlock (projected bill), SavingsOpportunityBlock (coupon),\n // UpcomingSubscriptionBlock (price per cadence).\n // `merchant_guid` / `merchant_name` — UpcomingBillBlock (bill row logo + name),\n // UpcomingSubscriptionBlock (hero logo + name).\n /** Dollar amount (unformatted); the block formats it as currency. */\n amount?: number\n /** Merchant guid used to render the inline / hero logo via `LogoFromGuid` (`MCH-...`). */\n merchant_guid?: string\n /** Merchant display name — shown as logo alt text and as the merchant/hero label. */\n merchant_name?: string\n // Upcoming Bill block (Projected Bill Payment): the block derives the Sun→Sat week strip\n // around `due_date` at render time.\n /** Due date of the projected bill in ISO form (e.g. `2025-10-30`). */\n due_date?: string\n // Savings Opportunity block (Save An Extra, Potential Savings, Embedded): purely data-driven\n // coupon card. Backend sends the caption and the amount, plus `slot` to toggle the green\n // gradient background when the card is embedded in a parent surface that supplies its own.\n /** Caption shown above the amount, e.g. `Save an extra` or `Potential savings`. */\n label?: string\n /**\n * Whether to render the green gradient slot behind the coupon. Defaults to true. Backend sends\n * `false` when the coupon is embedded in a parent surface that supplies its own background.\n */\n slot?: boolean\n // Upcoming Subscription block: billing cadence for the price pill (`${amount} / ${cadence}`).\n /** Billing cadence word that trails the price, e.g. `month` or `year`. */\n cadence?: string\n // Account block (status on/off-track, deposit, payoff variants): card content carried flat on\n // the slot (the V2 contract drops `instance_slot_data`). `amount`, `label`, `merchant_guid`,\n // `merchant_name`, `institution_guid`, `institution_name` are shared fields declared above.\n /** Secondary line beneath the amount on the standard card, e.g. \"Remaining after expenses\". */\n sub_text?: string\n /** Header bar text (standard card) or the colored category strip label (deposit cards). */\n header_text?: string\n /** Generic-tile icon name used when no merchant/institution logo is available. */\n icon_name?: string\n /** Category guid used to render the deposit-card logo fallback. */\n category_guid?: string\n // Debts block: `amount` is the current balance; the shared account/institution fields above.\n /** Projected payoff date in ISO form (e.g. `2027-03-01`); the block formats it as month + year. */\n payoff_date?: string\n /** Monthly payment toward the debt (unformatted); the block formats it as currency. */\n monthly_payment?: number\n /** Annual interest rate as a percentage (e.g. `19.99`); the block formats it as a percent. */\n interest_rate?: number\n}\n"],"mappings":"AAgTA,IAAa,IAAA,CACX,GACA,MACkB,IAAO,CAAA"}
1
+ {"version":3,"file":"Insights.es.js","names":[],"sources":["../../../src/core/types/Insights.ts"],"sourcesContent":["// ============ Core InsightsV2 Types ============\n\nimport { InsightsInstanceSlotData } from './InsightsInstanceSlotData'\n\nexport interface ThemedSVGImageProps {\n divProps?: React.HTMLAttributes<HTMLDivElement>\n image: React.ComponentType<React.SVGProps<SVGSVGElement>>\n isMini?: boolean\n}\n\n/**\n * Emitted by a block when the user drills into a specific datum (e.g. clicks a\n * chart bar). Named fields rather than positional args so blocks with differing\n * shapes can extend this without the call sites transposing values.\n */\nexport interface DrilldownPayload {\n chartBarIndex: number\n tabIndex?: number\n transaction_guid?: string\n block?: string\n}\n\n/**\n * Which envelope a beat was fetched with. `embedded` (the transaction-row pill + details-drawer\n * card) and `notification` are V2 additions; a surface asks for one with `widget_type=` on the fetch.\n */\nexport type WidgetType = 'full' | 'mini' | 'micro' | 'embedded' | 'notification'\n\n/**\n * V2: the transaction-row tag, its own small section of the `embedded` envelope (the same grammar\n * as `description` / `footer`, with room for a tone or an icon later). Omitted for an insight that\n * tags no transaction row. It deliberately is *not* `short_title`, which stays a per-variant\n * attribute with a second consumer (the bank-holiday sub-header).\n */\nexport interface Pill {\n text: string\n}\n\n/**\n * V2: facts a drilldown shows that the card does not (e.g. the account number for the Transaction\n * Details drawer). A flat hash shared by every CTA of the card, omitted when the insight has none.\n * Never carries copy or user actions (memo, tags, hide, flag come from the transaction store).\n */\nexport type DrilldownData = Record<string, string | number | boolean | null>\n\nexport interface InsightsPayload {\n widget_type: WidgetType\n instance_slot: InstanceSlot\n /**\n * V1 only. The v2 contract carries everything a block needs on `instance_slot.data`,\n * and omits this key entirely (see the LargeTransactionV2 payload). Blocks that still require it\n * get it as a required field through `BlockProps`, which re-declares it.\n */\n instance_slot_data?: InsightsInstanceSlotData\n description: Description\n primary_cta?: PrimaryCTA\n secondary_cta?: SecondaryCTA\n title?: string\n sub_title?: Subtitle\n /**\n * V2 rename of `sub_title`: a flat string, with the logo promoted to the payload-level `logo`\n * field below. `sub_title` wins when both are present.\n */\n subtitle?: string\n /** V2: header logo paired with the flat `subtitle`: an entity guid or a status icon (`LogoRef`). */\n logo?: LogoRef\n /** V2: which design branch the backend picked (e.g. `no_merchant`). */\n variant?: string\n /** V2, `embedded` envelope only: the transaction-row pill. */\n pill?: Pill\n /** V2: drilldown-only facts, e.g. `{ account_number: 'XXXXXXXX043' }`. */\n drilldown_data?: DrilldownData\n footer?: Footer\n /**\n * V2: the link inside the description: on the full card a drawer of its own (Low Account\n * Balance's \"Transactions ›\"); on mini and micro the card's action, sent instead of `primary_cta`.\n * Absent when the beat has no link.\n */\n in_description_cta?: InDescriptionCTA\n guid: string\n user_guid: string\n client_guid?: string\n /** Template name, e.g. `LargeTransactionV2`. */\n template?: string\n revision?: number\n /** Unix seconds. */\n created_at?: number\n /** Unix seconds. */\n updated_at?: number\n /** Unix seconds. */\n active_at?: number\n displayed_at?: number | null\n dismissed_at: number | null\n cta_clicked_at?: number | null\n has_been_displayed?: boolean\n is_dismissed: boolean\n is_deleted?: boolean\n is_hidden_by_system?: boolean\n is_obsolete?: boolean\n is_refreshable?: boolean\n is_sampled?: boolean\n is_zero_state?: boolean\n status?: string | null\n /**\n * V2 (LargeTransactionV2 onward): the entities the beat is about, carried on the payload so\n * action blocks do not have to reach back out to the beat envelope.\n */\n primary_account_guid?: string | null\n primary_transaction_guid?: string | null\n primary_category_guid?: string | null\n primary_merchant_guid?: string | null\n /**\n * V2: the repeating transaction a subscription beat is about (Upcoming Subscription, Subscription\n * Price Increase). Read by `recurring_transaction_block`, see\n * `actionBlocks/RecurringTransactionBlock/subscriptionBeats.ts`.\n */\n primary_repeating_transaction_guid?: string | null\n}\n\nexport interface Legends {\n label: string\n value: number\n additional_value?: number\n additional_value_type?: string\n value_type?: string\n}\n\nexport interface Logo {\n category_guid?: string\n category_name?: string\n institution_guid?: string\n institution_name?: string\n logo_color?: string\n /** Draw the `logo_name` icon filled (V2 `ICO-` logos). */\n logo_fill?: boolean\n logo_name?: string\n merchant_guid?: string\n merchant_name?: string\n}\n\nexport interface Subtitle {\n logo?: Logo\n text: string\n}\n\n/**\n * A V2 logo, shared by the header (`InsightsPayload.logo`) and every instance-slot row. It takes\n * one of two shapes:\n *\n * - **Entity**: `guid`, whose prefix (`INS-` / `MCH-` / `CAT-`) picks the logo component, plus an\n * optional `fallback_guid` for when that component's asset cannot load. Today that is the\n * category behind an `MCH-` guid, which `MerchantLogo` shows as a tile when the merchant image\n * is missing.\n * - **Status icon**: `icon` (an mx-icons name, e.g. `warning`) and `color` (a theme palette path,\n * e.g. `error.main`), for subheaders that show a state rather than an entity (V1's\n * `logo_name` / `logo_color`).\n *\n * `alt` is the accessible name for either shape. A logo sends one shape; if it sends both, `icon`\n * wins, as `logo_name` does in V1's `SubHeader`.\n */\nexport interface LogoRef {\n alt?: string\n color?: string\n fallback_guid?: string\n guid?: string\n icon?: string\n}\n\nexport interface CategoryLogo {\n category_guid: string\n category_name: string\n}\n\nexport interface MerchantLogo {\n merchant_guid: string\n merchant_name: string\n}\n\nexport interface InstitutionLogo {\n institution_guid: string\n institution_name: string\n}\n\nexport interface Description {\n text: string\n html_text: string\n}\n\n/**\n * Post message a CTA press sends to the host, resolved by the backend for the beat's current\n * state. Absent/null = the backend has not described one: the frontend uses the template's\n * interim `ctaPostMessages` entry if there is one, else sends no message. `payload` carries only\n * beat-specific extras; the frontend always adds `beat_guid`, `beat_template`, `user_guid` and\n * `action_string`.\n */\nexport interface CtaPostMessageMetadata {\n /** Post message event; defaults to `beat/cta`. */\n event?: string | null\n /** Operation the host should perform, e.g. `op_1`, `op_2`, `op_3`. Defaults to `op_1`. */\n action?: string | null\n /** Beat-specific fields merged into the message metadata (account ids, amounts, ...). */\n payload?: Record<string, unknown> | null\n}\n\nexport interface PrimaryCTA {\n label: string\n block: string\n variant?: string | null\n /**\n * What pressing the CTA does beyond opening its block, named by the backend (ditto\n * `primary_cta_action`, passed through by tupac). Looked up in `insights-v2/ctaActions`;\n * null / absent / unknown means the CTA only opens its block or posts its message.\n */\n action_key?: string | null\n metadata?: CtaPostMessageMetadata | null\n}\n\nexport interface SecondaryCTA {\n label: string\n /**\n * Drawer block to open. `null` when the CTA opens nothing (ditto `secondary_cta_block: null`,\n * e.g. Fee Detected's \"Contact Support\"): the press posts its message to the host instead.\n */\n block: string | null\n variant?: string | null\n /** See `PrimaryCTA.action_key` (ditto `secondary_cta_action`). */\n action_key?: string | null\n metadata?: CtaPostMessageMetadata | null\n}\n\n/**\n * The description link: its label, the action block it opens and, like a CTA's, the variant that\n * tells that block what to show (ditto's `in_description_cta_variant`, e.g. `low_balance`). On mini\n * and micro it words the card's action; `block` is empty when that action opens no drawer.\n */\nexport interface InDescriptionCTA {\n label: string\n block?: string\n variant?: string | null\n action_key?: string | null\n}\n\nexport interface Footer {\n /** V1: a pre-formatted date string. */\n date?: string\n /**\n * The account label, on both V1 and V2. The backend resolves the plurality: one account sends\n * its name (e.g. `Epic Bank`), several send a localized count (e.g. `2 Accounts`), none sends\n * nothing. There is deliberately no separate `accounts` key — see tupac's `footer_account_label`.\n */\n account?: string\n /**\n * V2 (LargeTransactionV2 onward): unix seconds, formatted by `Footer` for display.\n * Replaces `date`; `date` wins when a beat somehow sends both.\n */\n timestamp?: number\n}\n\n// ============ Instance Slot Types ============\n// Values are the snake_case block names the backend sends on a beat's instance slot; the PascalCase\n// keys stay as friendly references (e.g. BlockType.BarChartBlock === 'bar_chart_block').\nexport const BlockType = {\n AccountBlock: 'account_block',\n AccountSwitchBlock: 'account_switch_block',\n BarChartBlock: 'bar_chart_block',\n BudgetBlock: 'budget_block',\n ImageBlock: 'image_block',\n TransactionBlock: 'transaction_block',\n DonutChartBlock: 'donut_chart_block',\n DoubleBarChartBlock: 'double_bar_chart_block',\n DoubleProgressBarBlock: 'double_progress_bar_block',\n DebtsBlock: 'debts_block',\n SaveExtraBlock: 'save_extra_block',\n SavingsOpportunityBlock: 'savings_opportunity_block',\n StepChartBlock: 'step_chart_block',\n SVGImageBlock: 'svg_image_block',\n UpcomingBillBlock: 'upcoming_bill_block',\n UpcomingSubscriptionBlock: 'upcoming_subscription_block',\n WithdrawalBlock: 'withdrawal_block',\n} as const\n\nexport type BlockType = (typeof BlockType)[keyof typeof BlockType]\n\n/**\n * A pre-localized row on a V2 instance slot. The backend resolves the copy and formatting; the\n * logo is a `LogoRef` (an entity guid or a status icon, see `logoFromRef`).\n */\nexport interface InstanceSlotRow {\n amount?: number\n logo?: LogoRef\n primary_text?: string\n secondary_text?: string\n}\n\n/**\n * V2: the slots a block's variant filled, keyed by slot name; ditto owns the names and omits any\n * slot it has no value for (`lib/ditto/blocks/<block>.yml`). Read with `slot()`, which names the\n * kind the caller expects.\n */\nexport interface InstanceSlotData {\n [slot: string]: unknown\n}\n\n/**\n * Reads one slot off a block's `data`; undefined when ditto did not fill it.\n *\n * The caller names the kind, because the slot's kind lives in the block's ditto schema and not\n * here — a block fills slots with whatever its card needs, so no fixed list of kinds would hold\n * (`account_switch_block` alone carries a boolean and `budget_block` a nested object).\n */\nexport const slot = <T = unknown>(\n data: InstanceSlotData | undefined,\n name: string,\n): T | undefined => data?.[name] as T | undefined\n\n/**\n * V2: which block renders this beat's content, and what it renders.\n *\n * `block` is optional: a beat whose template has no ditto config arrives as an empty `{}` and the\n * card renders its copy and CTAs alone, so a reader cannot assume a block is named. One interface\n * with `block` optional rather than a union with `Record<string, never>`, which TypeScript absorbs\n * — that union left `block` reading as required and typed a promise it did not keep.\n *\n * `variant` is optional for the same reason — the empty `{}` carries neither. Every ditto beat\n * file that names a block also names a variant, so a *filled* slot always has one; ditto drops a\n * nil variant rather than sending null, which is why the type is `string | null | undefined`.\n */\nexport interface InstanceSlot {\n block?: BlockType\n variant?: string | null\n /** The slots this block's variant declares in ditto. */\n data?: InstanceSlotData\n // Direct Deposit block (Set Up Direct Deposit, Switch Direct Deposit, Missing\n // Interest Rate): account facts carried flat on the slot, beside `data`.\n /** Primary line on the hero card, e.g. \"Epic Bank Checking, *1234\". */\n account_name?: string\n /** Secondary line beneath the name, e.g. \"Checking Account\" / \"Credit Card\". */\n account_type?: string\n /** Status pill label, e.g. \"Direct Deposit Not Set Up\" / \"Interest Rate: 19.99% APR\". */\n status_text?: string\n institution_guid?: string\n institution_name?: string\n // Shared across multiple V2 component blocks:\n // `amount` — UpcomingBillBlock (projected bill), SavingsOpportunityBlock (coupon),\n // UpcomingSubscriptionBlock (price per cadence).\n // `merchant_guid` / `merchant_name` — UpcomingBillBlock (bill row logo + name),\n // UpcomingSubscriptionBlock (hero logo + name).\n /** Dollar amount (unformatted); the block formats it as currency. */\n amount?: number\n /** Merchant guid used to render the inline / hero logo via `LogoFromGuid` (`MCH-...`). */\n merchant_guid?: string\n /** Merchant display name — shown as logo alt text and as the merchant/hero label. */\n merchant_name?: string\n // Upcoming Bill block (Projected Bill Payment): the block derives the Sun→Sat week strip\n // around `due_date` at render time.\n /** Due date of the projected bill in ISO form (e.g. `2025-10-30`). */\n due_date?: string\n // Savings Opportunity block (Save An Extra, Potential Savings, Embedded): purely data-driven\n // coupon card. Backend sends the caption and the amount, plus `slot` to toggle the green\n // gradient background when the card is embedded in a parent surface that supplies its own.\n /** Caption shown above the amount, e.g. `Save an extra` or `Potential savings`. */\n label?: string\n /**\n * Whether to render the green gradient slot behind the coupon. Defaults to true. Backend sends\n * `false` when the coupon is embedded in a parent surface that supplies its own background.\n */\n slot?: boolean\n // Upcoming Subscription block: billing cadence for the price pill (`${amount} / ${cadence}`).\n /** Billing cadence word that trails the price, e.g. `month` or `year`. */\n cadence?: string\n // Account block (status on/off-track, deposit, payoff variants): card content carried flat on\n // the slot (the V2 contract drops `instance_slot_data`). `amount`, `label`, `merchant_guid`,\n // `merchant_name`, `institution_guid`, `institution_name` are shared fields declared above.\n /** Secondary line beneath the amount on the standard card, e.g. \"Remaining after expenses\". */\n sub_text?: string\n /** Header bar text (standard card) or the colored category strip label (deposit cards). */\n header_text?: string\n /** Generic-tile icon name used when no merchant/institution logo is available. */\n icon_name?: string\n /** Category guid used to render the deposit-card logo fallback. */\n category_guid?: string\n // Debts block: `amount` is the current balance; the shared account/institution fields above.\n /** Projected payoff date in ISO form (e.g. `2027-03-01`); the block formats it as month + year. */\n payoff_date?: string\n /** Monthly payment toward the debt (unformatted); the block formats it as currency. */\n monthly_payment?: number\n /** Annual interest rate as a percentage (e.g. `19.99`); the block formats it as a percent. */\n interest_rate?: number\n}\n"],"mappings":"AAsTA,IAAa,IAAA,CACX,GACA,MACkB,IAAO,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { DataSeries, Legends } from '../../core';
2
- export interface InsightsInstanceSlotData extends Partial<BarChartBlockData>, Partial<BudgetBlockData>, Partial<DonutChartBlockData>, Partial<DoubleProgressBarBlockData>, Partial<ImageBlockData>, Partial<AccountBlockData>, Partial<SaveExtraBlockData>, Partial<StepChartBlockData>, Partial<SVGImageBlockData>, Partial<AccountSwitchBlockData>, Partial<TransactionDetailsBlockData>, Partial<CommonProps> {
2
+ export interface InsightsInstanceSlotData extends Partial<BudgetBlockData>, Partial<DonutChartBlockData>, Partial<DoubleProgressBarBlockData>, Partial<ImageBlockData>, Partial<AccountBlockData>, Partial<SaveExtraBlockData>, Partial<StepChartBlockData>, Partial<SVGImageBlockData>, Partial<AccountSwitchBlockData>, Partial<TransactionDetailsBlockData>, Partial<CommonProps> {
3
3
  }
4
4
  interface CommonProps {
5
5
  amount?: number;
@@ -12,8 +12,12 @@ interface CommonProps {
12
12
  primary_transaction_guid?: string;
13
13
  }
14
14
  export interface BarChartBlockData {
15
+ series?: DataSeries;
16
+ category_guid?: string;
15
17
  average_amount?: number;
16
18
  ariaLabel?: string;
19
+ /** [0] monthly amount, [1] trend. */
20
+ additional_data?: Legends[];
17
21
  }
18
22
  interface Main {
19
23
  value: string;
@@ -1 +1 @@
1
- {"version":3,"file":"InsightsInstanceSlotData.es.js","names":[],"sources":["../../../src/core/types/InsightsInstanceSlotData.ts"],"sourcesContent":["import type { DataSeries, Legends } from '../../core'\n\nexport interface InsightsInstanceSlotData\n extends\n Partial<BarChartBlockData>,\n Partial<BudgetBlockData>,\n Partial<DonutChartBlockData>,\n Partial<DoubleProgressBarBlockData>,\n Partial<ImageBlockData>,\n Partial<AccountBlockData>,\n Partial<SaveExtraBlockData>,\n Partial<StepChartBlockData>,\n Partial<SVGImageBlockData>,\n Partial<AccountSwitchBlockData>,\n Partial<TransactionDetailsBlockData>,\n Partial<CommonProps> {}\n\n//when any of the type is used more than one times, we can use the common props\ninterface CommonProps {\n amount?: number\n date?: string\n legends?: Legends[]\n category_guid?: string\n data_series?: DataSeries | DataSet[]\n transaction_guids?: string[]\n account_guids?: string[]\n primary_transaction_guid?: string\n}\n\n//BarChart Block\nexport interface BarChartBlockData {\n average_amount?: number\n ariaLabel?: string\n}\n\n//DonutChart Block\ninterface Main {\n value: string\n value_type: string\n label: string\n}\nexport interface DonutChartBlockData {\n main: Main\n}\n\n//DoubleBarChart Block\n// TODO : This has to be revisited again to update the below types based on API response once we have the final shape of the data_series for double bar chart from BE\nexport interface LegendProps extends Legends {\n amount: number\n formattedAmount: string\n label: string\n color?: string\n}\n\nexport interface DataSet extends DataSeries {\n ariaLabelComparison: string\n ariaLabelMain: string\n comparison: number\n formattedComparison: string\n formattedMain: string\n label: string\n main: number\n}\n\n//DoubleProgressBar Block\n\ninterface DoubleProgressBarProps {\n label: string\n value: number\n}\nexport interface DoubleProgressBarBlockData {\n doubleProgressBar: {\n previous: DoubleProgressBarProps\n latest: DoubleProgressBarProps\n }\n}\n\n//Image Block\nexport interface ImageBlockData {\n image: string\n}\n\n//Account Block\nexport interface AccountBlockData {\n sub_text: string\n institution_guid?: string\n institution_name?: string\n icon_name?: string\n /** Header bar text (standard card), or the colored category strip label (deposit cards). */\n header_text?: string\n // Deposit variants (Unified Deposit, Unified Deposit Emergency Fund, Savings Account Deposit)\n /** Merchant guid — renders a real merchant logo in the deposit card when present. */\n merchant_guid?: string\n /** Merchant display name — logo alt text and the payer line under the amount. */\n merchant_name?: string\n /** Secondary label beside the amount, e.g. `On {date}, you saved` or `Balance as of MM/DD/YY`. */\n label?: string\n}\n\nexport interface SaveExtraBlockData {\n /** Styled segments `[lead-in, amount digits, trailing copy]`, e.g. `['Save an extra', '100', 'to help your funds grow']`. */\n primary_text?: string[]\n /** Styled segments `[projected balance, caption]`, e.g. `['$8,313.87', 'After payday & projected expenses']`. */\n secondary_text?: string[]\n /** MakeTransfer drilldown: available balance (both variants). */\n available_balance?: number\n /** SAVE_ENOUGH_TO_LIVE_ON: average monthly spend. */\n avg_monthly_spend?: number\n /** SAVE_ENOUGH_TO_LIVE_ON: how long the balance lasts, overlaid on the timeline SVG (e.g. \"2 months, 11 days\"). */\n time_period?: string\n /** SAVE_AN_EXTRA_100: upcoming expenses (the \"Expenses\" figure). */\n upcoming_expenses?: number\n /** SAVE_AN_EXTRA_100: total remaining after expenses. */\n total_remaining?: number\n /** SAVE_ENOUGH_TO_LIVE_ON: date for the \"Your available balances as of {date}\" line. */\n date?: string\n}\n\n// AccountSwitch Block. State comes from `instance_slot.variant`, not a data flag.\nexport interface AccountSwitchBlockData {\n discovered_institution_guid: string\n discovered_institution_name: string\n held_institution_guid: string\n held_institution_name: string\n}\n\n// StepChart Block\nexport interface StepChartBlockData {\n completed_steps: number\n label_1: string\n label_2?: string\n}\n\n//Budgets Blocks\nexport enum BudgetTierType {\n LOW_BUDGET_TIER = 'LOW',\n MEDIUM_BUDGET_TIER = 'MEDIUM',\n OFF_TRACK_BUDGET_TIER = 'OFF_TRACK',\n}\n\nexport type BudgetTierValue = `${BudgetTierType}`\n\nexport interface BudgetLocalizedPayload {\n primary_text?: string\n amount_left_label?: string\n spent_label?: string\n budgeted_label?: string\n}\n\nexport interface BudgetBlockData {\n budget_percent: number\n budget_tier: BudgetTierValue\n category_guid?: string\n merchant_guid?: string\n spent_amount: number\n budgeted_amount: number\n localized_payload: BudgetLocalizedPayload\n}\n\nexport interface SVGImageBlockData {\n isCIBC?: boolean\n}\n\n// TransactionDetails Action Block\n// The drawer's subject is `InsightsPayload.primary_transaction_guid`; only action configuration\n// lives here.\nexport interface TransactionDetailsBlockData {\n /** `TopActions` member names, e.g. `['Category', 'Date', 'Memo']`. Omit for the defaults. */\n top_actions?: string[]\n /** `BottomActions` member names, e.g. `['MerchantBudget', 'HideTransaction']`. Omit for defaults. */\n bottom_actions?: string[]\n}\n"],"mappings":"AAsIA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,kBAAA,OACA,EAAA,qBAAA,UACA,EAAA,wBAAA;AACF,GAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"InsightsInstanceSlotData.es.js","names":[],"sources":["../../../src/core/types/InsightsInstanceSlotData.ts"],"sourcesContent":["import type { DataSeries, Legends } from '../../core'\n\nexport interface InsightsInstanceSlotData\n extends\n Partial<BudgetBlockData>,\n Partial<DonutChartBlockData>,\n Partial<DoubleProgressBarBlockData>,\n Partial<ImageBlockData>,\n Partial<AccountBlockData>,\n Partial<SaveExtraBlockData>,\n Partial<StepChartBlockData>,\n Partial<SVGImageBlockData>,\n Partial<AccountSwitchBlockData>,\n Partial<TransactionDetailsBlockData>,\n Partial<CommonProps> {}\n\n//when any of the type is used more than one times, we can use the common props\ninterface CommonProps {\n amount?: number\n date?: string\n legends?: Legends[]\n category_guid?: string\n data_series?: DataSeries | DataSet[]\n transaction_guids?: string[]\n account_guids?: string[]\n primary_transaction_guid?: string\n}\n\n//BarChart Block: `instance_slot.data` (Insights 2.0)\nexport interface BarChartBlockData {\n series?: DataSeries\n category_guid?: string\n average_amount?: number\n ariaLabel?: string\n /** [0] monthly amount, [1] trend. */\n additional_data?: Legends[]\n}\n\n//DonutChart Block\ninterface Main {\n value: string\n value_type: string\n label: string\n}\nexport interface DonutChartBlockData {\n main: Main\n}\n\n//DoubleBarChart Block\n// TODO : This has to be revisited again to update the below types based on API response once we have the final shape of the data_series for double bar chart from BE\nexport interface LegendProps extends Legends {\n amount: number\n formattedAmount: string\n label: string\n color?: string\n}\n\nexport interface DataSet extends DataSeries {\n ariaLabelComparison: string\n ariaLabelMain: string\n comparison: number\n formattedComparison: string\n formattedMain: string\n label: string\n main: number\n}\n\n//DoubleProgressBar Block\n\ninterface DoubleProgressBarProps {\n label: string\n value: number\n}\nexport interface DoubleProgressBarBlockData {\n doubleProgressBar: {\n previous: DoubleProgressBarProps\n latest: DoubleProgressBarProps\n }\n}\n\n//Image Block\nexport interface ImageBlockData {\n image: string\n}\n\n//Account Block\nexport interface AccountBlockData {\n sub_text: string\n institution_guid?: string\n institution_name?: string\n icon_name?: string\n /** Header bar text (standard card), or the colored category strip label (deposit cards). */\n header_text?: string\n // Deposit variants (Unified Deposit, Unified Deposit Emergency Fund, Savings Account Deposit)\n /** Merchant guid — renders a real merchant logo in the deposit card when present. */\n merchant_guid?: string\n /** Merchant display name — logo alt text and the payer line under the amount. */\n merchant_name?: string\n /** Secondary label beside the amount, e.g. `On {date}, you saved` or `Balance as of MM/DD/YY`. */\n label?: string\n}\n\nexport interface SaveExtraBlockData {\n /** Styled segments `[lead-in, amount digits, trailing copy]`, e.g. `['Save an extra', '100', 'to help your funds grow']`. */\n primary_text?: string[]\n /** Styled segments `[projected balance, caption]`, e.g. `['$8,313.87', 'After payday & projected expenses']`. */\n secondary_text?: string[]\n /** MakeTransfer drilldown: available balance (both variants). */\n available_balance?: number\n /** SAVE_ENOUGH_TO_LIVE_ON: average monthly spend. */\n avg_monthly_spend?: number\n /** SAVE_ENOUGH_TO_LIVE_ON: how long the balance lasts, overlaid on the timeline SVG (e.g. \"2 months, 11 days\"). */\n time_period?: string\n /** SAVE_AN_EXTRA_100: upcoming expenses (the \"Expenses\" figure). */\n upcoming_expenses?: number\n /** SAVE_AN_EXTRA_100: total remaining after expenses. */\n total_remaining?: number\n /** SAVE_ENOUGH_TO_LIVE_ON: date for the \"Your available balances as of {date}\" line. */\n date?: string\n}\n\n// AccountSwitch Block. State comes from `instance_slot.variant`, not a data flag.\nexport interface AccountSwitchBlockData {\n discovered_institution_guid: string\n discovered_institution_name: string\n held_institution_guid: string\n held_institution_name: string\n}\n\n// StepChart Block\nexport interface StepChartBlockData {\n completed_steps: number\n label_1: string\n label_2?: string\n}\n\n//Budgets Blocks\nexport enum BudgetTierType {\n LOW_BUDGET_TIER = 'LOW',\n MEDIUM_BUDGET_TIER = 'MEDIUM',\n OFF_TRACK_BUDGET_TIER = 'OFF_TRACK',\n}\n\nexport type BudgetTierValue = `${BudgetTierType}`\n\nexport interface BudgetLocalizedPayload {\n primary_text?: string\n amount_left_label?: string\n spent_label?: string\n budgeted_label?: string\n}\n\nexport interface BudgetBlockData {\n budget_percent: number\n budget_tier: BudgetTierValue\n category_guid?: string\n merchant_guid?: string\n spent_amount: number\n budgeted_amount: number\n localized_payload: BudgetLocalizedPayload\n}\n\nexport interface SVGImageBlockData {\n isCIBC?: boolean\n}\n\n// TransactionDetails Action Block\n// The drawer's subject is `InsightsPayload.primary_transaction_guid`; only action configuration\n// lives here.\nexport interface TransactionDetailsBlockData {\n /** `TopActions` member names, e.g. `['Category', 'Date', 'Memo']`. Omit for the defaults. */\n top_actions?: string[]\n /** `BottomActions` member names, e.g. `['MerchantBudget', 'HideTransaction']`. Omit for defaults. */\n bottom_actions?: string[]\n}\n"],"mappings":"AAyIA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,kBAAA,OACA,EAAA,qBAAA,UACA,EAAA,wBAAA;AACF,GAAA,CAAA,CAAA"}
@@ -1,8 +1,8 @@
1
1
  import { useGlobalCopyStore as C, useGlobalUiStore as _, useInsightsV2Store as h } from "../../common/context/hooks.es.js";
2
2
  import B from "../../common/components/drawer/Drawer.es.js";
3
3
  import v from "../../common/components/Loader.es.js";
4
- import { getDynamicCtaBasedOnTriggers as w } from "./util.es.js";
5
- import { hasDrawerBlock as D } from "../mappings/hasDrawerBlock.es.js";
4
+ import { hasDrawerBlock as w } from "../mappings/hasDrawerBlock.es.js";
5
+ import { getDynamicCtaBasedOnTriggers as D } from "./util.es.js";
6
6
  import { actionBlocks as b } from "../mappings/blocks.es.js";
7
7
  import { observer as L } from "mobx-react-lite";
8
8
  import x from "@mui/material/Stack";
@@ -16,7 +16,7 @@ var m = ({ actionBlock: s, ...o }) => {
16
16
  if (!o.insights_payload) return null;
17
17
  const { primary_cta: u, secondary_cta: f, in_description_cta: k } = o.insights_payload, a = c.isDrawerOpen && c.guid === o.guid;
18
18
  if (!p) return a ? /* @__PURE__ */ e(v, {}) : null;
19
- const r = w(c, u, f, k), l = D(r?.block), t = l ? b[r?.block] : void 0;
19
+ const r = D(c, u, f, k), l = w(r?.block), t = l ? b[r?.block] : void 0;
20
20
  if (t?.presentation === "modal") return a ? /* @__PURE__ */ e(m, {
21
21
  actionBlock: t,
22
22
  beat: o
@@ -1,39 +1,41 @@
1
- import { buildDynamicCopy as F } from "../../../core/utils/Localization.es.js";
2
- import G from "../../../common/utils/AccountDisplayName.es.js";
3
- import { useGlobalCopyStore as W, useInsightsV2Store as j, useSettingsStore as z, useUserStore as q } from "../../../common/context/hooks.es.js";
4
- import J from "../../../common/components/Loader.es.js";
5
- import K from "../../../common/components/CurrencyDialog.es.js";
6
- import { useBeatActions as Q } from "../../beatActions.es.js";
7
- import { getDynamicCtaBasedOnTriggers as X } from "../util.es.js";
8
- import { useCtaHandler as Y } from "../../ctaActions/useCtaAction.es.js";
9
- import { AMOUNT_INPUT_VARIANTS as Z, findLowBalanceProfile as oo, isAmountInputVariant as L, isWholeAmount as to, toInputValue as eo } from "./layout.es.js";
1
+ import { buildDynamicCopy as j } from "../../../core/utils/Localization.es.js";
2
+ import z from "../../../common/utils/AccountDisplayName.es.js";
3
+ import { useGlobalCopyStore as q, useInsightsV2Store as J, useSettingsStore as K, useUserStore as Q } from "../../../common/context/hooks.es.js";
4
+ import X from "../../../common/components/Loader.es.js";
5
+ import Z from "../../../common/components/CurrencyDialog.es.js";
6
+ import { useBeatActions as oo } from "../../beatActions.es.js";
7
+ import { ANALYTICS_EVENTS_CONFIG as c } from "../../analytics/analyticsEventsConfig.es.js";
8
+ import { useCtaHandler as to } from "../../ctaActions/useCtaAction.es.js";
9
+ import { useAnalyticsEvent as eo } from "../../analytics/useAnalyticsEvent.es.js";
10
+ import { getDynamicCtaBasedOnTriggers as io } from "../util.es.js";
11
+ import { AMOUNT_INPUT_VARIANTS as no, findLowBalanceProfile as ro, isAmountInputVariant as x, isWholeAmount as ao, toInputValue as so } from "./layout.es.js";
10
12
  import r from "react";
11
- import { observer as io } from "mobx-react-lite";
12
- import T from "@mui/material/Stack";
13
- import { H3 as no, InstitutionLogo as ro, Text as P } from "@mxenabled/mxui";
14
- import { Icon as ao } from "@mxenabled/mx-icons";
13
+ import { observer as co } from "mobx-react-lite";
14
+ import P from "@mui/material/Stack";
15
+ import { H3 as lo, InstitutionLogo as uo, Text as H } from "@mxenabled/mxui";
16
+ import { Icon as mo } from "@mxenabled/mx-icons";
15
17
  import { jsx as e, jsxs as k } from "react/jsx-runtime";
16
- import so from "@mui/material/Dialog";
17
- import co from "@mui/material/IconButton";
18
- var D = ({ children: y, closeAriaLabel: i, heading: o, onClose: l }) => {
18
+ import po from "@mui/material/Dialog";
19
+ import _o from "@mui/material/IconButton";
20
+ var w = ({ children: I, closeAriaLabel: i, heading: o, onClose: l }) => {
19
21
  const u = r.useId();
20
- return /* @__PURE__ */ e(so, {
22
+ return /* @__PURE__ */ e(po, {
21
23
  "aria-labelledby": o ? u : void 0,
22
24
  maxWidth: "xs",
23
25
  onClose: l,
24
26
  open: !0,
25
- children: /* @__PURE__ */ k(T, {
27
+ children: /* @__PURE__ */ k(P, {
26
28
  sx: {
27
29
  gap: 12,
28
30
  p: 24,
29
31
  position: "relative"
30
32
  },
31
33
  children: [
32
- o && /* @__PURE__ */ e(no, {
34
+ o && /* @__PURE__ */ e(lo, {
33
35
  id: u,
34
36
  children: o
35
37
  }),
36
- /* @__PURE__ */ e(co, {
38
+ /* @__PURE__ */ e(_o, {
37
39
  "aria-label": i || "Close",
38
40
  onClick: l,
39
41
  sx: {
@@ -41,88 +43,91 @@ var D = ({ children: y, closeAriaLabel: i, heading: o, onClose: l }) => {
41
43
  right: 8,
42
44
  top: 18
43
45
  },
44
- children: /* @__PURE__ */ e(ao, {
46
+ children: /* @__PURE__ */ e(mo, {
45
47
  name: "close",
46
48
  sx: { color: "action.active" }
47
49
  })
48
50
  }),
49
- y
51
+ I
50
52
  ]
51
53
  })
52
54
  });
53
- }, Lo = io(function({ beat: i }) {
54
- const { common: o, insights_feed: l } = W(), { actionDrawer: u, closeActionDrawer: c } = j(), f = z(), { userInsightProfile: v } = q(), b = Y(i, Q()), { primary_cta: B, secondary_cta: N } = i.insights_payload ?? {}, s = X(u, B, N)?.variant, a = l?.amount_input_modal, t = s === Z.LOW_BALANCE_THRESHOLD, _ = t ? oo(f.notificationProfiles, i.primary_account_guid) : void 0, I = t ? _?.threshold : v?.savings_opportunity_minimum_checking_account_balance, [M, V] = r.useState(t), m = r.useRef(!0);
55
- r.useEffect(() => (m.current = !0, () => {
56
- m.current = !1;
55
+ }, ko = co(function({ beat: i }) {
56
+ const { common: o, insights_feed: l } = q(), { actionDrawer: u, closeActionDrawer: m } = J(), f = K(), { userInsightProfile: v } = Q(), S = to(i, oo()), T = eo(), { primary_cta: B, secondary_cta: O, in_description_cta: V } = i.insights_payload ?? {}, s = io(u, B, O, V)?.variant, a = l?.amount_input_modal, t = s === no.LOW_BALANCE_THRESHOLD, h = t ? ro(f.notificationProfiles, i.primary_account_guid) : void 0, E = t ? h?.threshold : v?.savings_opportunity_minimum_checking_account_balance, [G, R] = r.useState(t), d = r.useRef(!0);
57
+ r.useEffect(() => (d.current = !0, () => {
58
+ d.current = !1;
57
59
  }), []), r.useEffect(() => {
58
60
  t && f.loadNotificationProfiles().finally(() => {
59
- m.current && V(!1);
61
+ d.current && R(!1);
60
62
  });
61
63
  }, [t, f]);
62
- const [E, H] = r.useState(null), [S, A] = r.useState(!1), [O, h] = r.useState(!1), d = E ?? eo(I);
63
- if (M) return /* @__PURE__ */ e(D, {
64
+ const [F, M] = r.useState(null), [A, C] = r.useState(!1), [U, y] = r.useState(!1), p = F ?? so(E);
65
+ if (G) return /* @__PURE__ */ e(w, {
64
66
  closeAriaLabel: o?.close_aria,
65
- onClose: c,
66
- children: /* @__PURE__ */ e(J, {})
67
+ onClose: m,
68
+ children: /* @__PURE__ */ e(X, {})
67
69
  });
68
- const n = L(s) ? a?.[s] : void 0, x = !!n?.title && !!n.description && !!n.input_label && !!a?.whole_number_error && !!a.save_error && !!o?.save_button && (!t || !!o.cancel_button) && !!o.close_aria;
69
- if (!a || !n || !x || !(t ? _ : v))
70
- return console.warn(`amount_input_modal_block: ${a ? L(s) ? x ? t ? "no low-balance profile for the account" : "user insight profile not set by the host" : `copy incomplete for "${s}"` : `unknown variant "${s}"` : "copy namespace missing"}`), /* @__PURE__ */ e(D, {
70
+ const n = x(s) ? a?.[s] : void 0, b = !!n?.title && !!n.description && !!n.input_label && !!a?.whole_number_error && !!a.save_error && !!o?.save_button && (!t || !!o.cancel_button) && !!o.close_aria;
71
+ if (!a || !n || !b || !(t ? h : v))
72
+ return console.warn(`amount_input_modal_block: ${a ? x(s) ? b ? t ? "no low-balance profile for the account" : "user insight profile not set by the host" : `copy incomplete for "${s}"` : `unknown variant "${s}"` : "copy namespace missing"}`), /* @__PURE__ */ e(w, {
71
73
  closeAriaLabel: o?.close_aria,
72
74
  heading: o?.error_heading,
73
- onClose: c,
74
- children: /* @__PURE__ */ e(P, { children: o?.error_message })
75
+ onClose: m,
76
+ children: /* @__PURE__ */ e(H, { children: o?.error_message })
75
77
  });
76
- const C = !t && !!I, w = i.primary_account ? G(i.primary_account) : "", g = to(d), R = d !== "" && !g, U = async () => {
77
- if (!g || S) return;
78
- const p = Number(d);
79
- A(!0), h(!1);
80
- const $ = t ? await b("updateNotificationProfileThreshold", {
81
- profileGuid: _?.guid,
82
- threshold: p
83
- }) : await b("updateUserInsightProfile", { fields: { savings_opportunity_minimum_checking_account_balance: p } });
84
- m.current && (A(!1), $ ? c() : h(!0));
78
+ const D = () => {
79
+ T(t ? c.EDIT_INSIGHT_THRESHOLD_CANCELED : c.EDIT_SAFETY_NET_CANCEL), m();
80
+ }, L = !t && !!E, N = i.primary_account ? z(i.primary_account) : "", g = ao(p), $ = p !== "" && !g, W = async () => {
81
+ if (!g || A) return;
82
+ const _ = Number(p);
83
+ C(!0), y(!1);
84
+ const Y = t ? await S("updateNotificationProfileThreshold", {
85
+ profileGuid: h?.guid,
86
+ threshold: _
87
+ }, { analytics: c.EDIT_INSIGHT_THRESHOLD_SAVE }) : await S("updateUserInsightProfile", { fields: { savings_opportunity_minimum_checking_account_balance: _ } }, { analytics: c.EDIT_SAFETY_NET_SAVE });
88
+ d.current && (C(!1), Y ? m() : y(!0));
85
89
  };
86
- return /* @__PURE__ */ e(K, {
90
+ return /* @__PURE__ */ e(Z, {
87
91
  closeAriaLabel: o.close_aria,
88
- content: F(C && n.description_edit || n.description, /* @__PURE__ */ e("strong", { children: w }, "account")),
89
- errorText: R ? a.whole_number_error : O ? a.save_error : void 0,
90
- handleInputChange: (p) => {
91
- H(p), h(!1);
92
+ content: j(L && n.description_edit || n.description, /* @__PURE__ */ e("strong", { children: N }, "account")),
93
+ errorText: $ ? a.whole_number_error : U ? a.save_error : void 0,
94
+ handleInputChange: (_) => {
95
+ M(_), y(!1);
92
96
  },
93
- handleModalClose: c,
97
+ handleInputClick: t ? () => T(c.EDIT_INSIGHT_THRESHOLD_INPUT_SELECTED) : void 0,
98
+ handleModalClose: D,
94
99
  handlePrimaryAction: () => {
95
- U();
100
+ W();
96
101
  },
97
- handleSecondaryAction: c,
102
+ handleSecondaryAction: D,
98
103
  inputLabel: n.input_label,
99
- inputValue: d,
104
+ inputValue: p,
100
105
  isOpen: !0,
101
- isPrimaryDisabled: S || !g,
106
+ isPrimaryDisabled: A || !g,
102
107
  primaryText: o.save_button,
103
108
  secondaryText: t ? o.cancel_button : void 0,
104
- subtitle: t && i.primary_account ? /* @__PURE__ */ k(T, {
109
+ subtitle: t && i.primary_account ? /* @__PURE__ */ k(P, {
105
110
  sx: {
106
111
  alignItems: "center",
107
112
  flexDirection: "row",
108
113
  gap: 8
109
114
  },
110
- children: [/* @__PURE__ */ e(ro, {
115
+ children: [/* @__PURE__ */ e(uo, {
111
116
  alt: "",
112
117
  institutionGuid: i.primary_account.institution_guid ?? "",
113
118
  size: 16
114
- }), /* @__PURE__ */ e(P, {
119
+ }), /* @__PURE__ */ e(H, {
115
120
  color: "text.secondary",
116
121
  uppercase: !0,
117
122
  variant: "body2",
118
- children: w
123
+ children: N
119
124
  })]
120
125
  }) : void 0,
121
- title: C && n.title_edit || n.title
126
+ title: L && n.title_edit || n.title
122
127
  });
123
128
  });
124
129
  export {
125
- Lo as AmountInputModalBlock
130
+ ko as AmountInputModalBlock
126
131
  };
127
132
 
128
133
  //# sourceMappingURL=AmountInputModalBlock.es.js.map