@mx-cartographer/experiences 9.5.3 → 9.6.0
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 +7 -0
- package/dist/common/components/CurrencyDialog.d.ts +10 -2
- package/dist/common/components/CurrencyDialog.es.js +56 -50
- package/dist/common/components/CurrencyDialog.es.js.map +1 -1
- package/dist/core/index.es.js +111 -109
- package/dist/core/types/Insights.d.ts +33 -16
- package/dist/core/types/Insights.es.js +6 -0
- package/dist/core/types/Insights.es.js.map +1 -0
- package/dist/core/types/index.d.ts +2 -1
- package/dist/core/types/localization/InsightsFeedCopy.d.ts +21 -0
- package/dist/core/types/localization/index.d.ts +1 -1
- package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js +31 -25
- package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js.map +1 -1
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/AmountInputModalBlock.d.ts +13 -0
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/AmountInputModalBlock.es.js +128 -0
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/AmountInputModalBlock.es.js.map +1 -0
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/index.d.ts +1 -0
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/layout.d.ts +14 -0
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/layout.es.js +14 -0
- package/dist/insights-v2/actionBlocks/AmountInputModalBlock/layout.es.js.map +1 -0
- package/dist/insights-v2/blocks/ChartBlocks/DonutChartBlock/utils.d.ts +1 -1
- package/dist/insights-v2/blocks/ChartBlocks/DonutChartBlock/utils.es.js.map +1 -1
- package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/layout.d.ts +1 -1
- package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/layout.es.js.map +1 -1
- package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/IconComponent.d.ts +1 -1
- package/dist/insights-v2/blocks/ComponentBlocks/AccountBlock/IconComponent.es.js.map +1 -1
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.d.ts +5 -2
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js +36 -35
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js.map +1 -1
- package/dist/insights-v2/blocks/ComponentBlocks/WithdrawalBlock/WithdrawalBlock.d.ts +2 -2
- package/dist/insights-v2/blocks/ComponentBlocks/WithdrawalBlock/WithdrawalBlock.es.js +6 -5
- package/dist/insights-v2/blocks/ComponentBlocks/WithdrawalBlock/WithdrawalBlock.es.js.map +1 -1
- package/dist/insights-v2/blocks/ImageBlocks/SVGImageBlock/layout.d.ts +1 -1
- package/dist/insights-v2/blocks/ImageBlocks/SVGImageBlock/layout.es.js.map +1 -1
- package/dist/insights-v2/components/BaseLayout.es.js +22 -22
- package/dist/insights-v2/components/CompactInsightCard.d.ts +4 -4
- package/dist/insights-v2/components/CompactInsightCard.es.js +50 -46
- package/dist/insights-v2/components/CompactInsightCard.es.js.map +1 -1
- package/dist/insights-v2/ctaActions/runCtaAction.es.js +10 -10
- package/dist/insights-v2/ctaActions/runCtaAction.es.js.map +1 -1
- package/dist/insights-v2/index.es.js +17 -17
- package/dist/insights-v2/mappings/actionBlocksKey.d.ts +1 -0
- package/dist/insights-v2/mappings/actionBlocksKey.es.js +2 -1
- package/dist/insights-v2/mappings/actionBlocksKey.es.js.map +1 -1
- package/dist/insights-v2/mappings/blocks.d.ts +2 -1
- package/dist/insights-v2/mappings/blocks.es.js +62 -62
- package/dist/insights-v2/mappings/blocks.es.js.map +1 -1
- package/dist/insights-v2/mappings/hasDrawerBlock.d.ts +1 -0
- package/dist/insights-v2/mappings/hasDrawerBlock.es.js +13 -0
- package/dist/insights-v2/mappings/hasDrawerBlock.es.js.map +1 -0
- package/dist/insights-v2/resolveInsightRender.d.ts +8 -5
- package/dist/insights-v2/resolveInsightRender.es.js.map +1 -1
- package/dist/microinsights/cards/InsightCard.es.js +32 -31
- package/dist/microinsights/cards/InsightCard.es.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [9.5.4] - 10-09-2026
|
|
2
|
+
|
|
3
|
+
- **ADDED** - `amount_input_modal_block`, the first modal action block: edits one whole-dollar setting in a dialog, picked by the CTA variant. `low_balance_threshold` (Low Account Balance "Edit Alert Settings") saves the threshold on the account's low-balance alert profile; `safety_net` (Savings Opportunity V2 "Set Reminder" / "Adjust Reminder") saves the safety net on the user insight profile. Saves run through `useCtaHandler`. Copy under `insights_feed.amount_input_modal`; mock beats, stories and `docs/action-blocks/amount-input-modal-block.md`.
|
|
4
|
+
- **ADDED** - `ActionBlockEntry.presentation: 'modal'`: `ActionBlockLayer` renders such a block without the drawer, and only while it is open for its beat.
|
|
5
|
+
- **ADDED** - Optional `CurrencyDialog` props `subtitle`, `errorText` and `isPrimaryDisabled`; `content` now accepts a node. Its helper text (validation or save error) is now announced with `role="alert"`. Existing callers are otherwise unchanged.
|
|
6
|
+
- **CHANGED** - `hasDrawerBlock` moved to `insights-v2/mappings/hasDrawerBlock.ts` (still re-exported from `mappings/blocks`) so action blocks can import `ctaActions` without an import cycle.
|
|
7
|
+
|
|
1
8
|
## [9.5.3] - 10-09-2026
|
|
2
9
|
|
|
3
10
|
- **CHANGED** - Repeating-transaction create flows show Sherlock-ineligible rows disabled instead of hiding them; `SelectTransaction` drives `TransactionList`'s new `isRowDisabled` prop instead of `filter` (MEW-4143)
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
1
2
|
import { ButtonProps } from '@mui/material/Button';
|
|
2
3
|
interface CurrencyDialogProps {
|
|
3
4
|
closeAriaLabel: string;
|
|
4
|
-
|
|
5
|
+
/** Body copy; a node so callers can emphasise part of it (e.g. a bold account name). */
|
|
6
|
+
content?: ReactNode;
|
|
7
|
+
/** Validation or save error, shown under the input and marking it invalid. */
|
|
8
|
+
errorText?: string;
|
|
5
9
|
inputLabel?: string;
|
|
6
10
|
inputValue?: string;
|
|
7
11
|
isOpen: boolean;
|
|
12
|
+
/** Disables the primary button on top of the built-in input check (e.g. while saving). */
|
|
13
|
+
isPrimaryDisabled?: boolean;
|
|
8
14
|
handleInputChange?: (value: string) => void;
|
|
9
15
|
handleModalClose: () => void;
|
|
10
16
|
handlePrimaryAction: () => void;
|
|
@@ -13,7 +19,9 @@ interface CurrencyDialogProps {
|
|
|
13
19
|
primaryText: string;
|
|
14
20
|
secondaryColor?: ButtonProps['color'];
|
|
15
21
|
secondaryText?: string;
|
|
22
|
+
/** A line under the title, e.g. the account a setting applies to. */
|
|
23
|
+
subtitle?: ReactNode;
|
|
16
24
|
title: string;
|
|
17
25
|
}
|
|
18
|
-
declare const CurrencyDialog: ({ closeAriaLabel, content, inputLabel, inputValue, isOpen, handleInputChange, handleModalClose, handlePrimaryAction, handleSecondaryAction, primaryColor, primaryText, secondaryColor, secondaryText, title, }: CurrencyDialogProps) => import("react/jsx-runtime").JSX.Element;
|
|
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;
|
|
19
27
|
export default CurrencyDialog;
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { useScreenSize as
|
|
2
|
-
import
|
|
3
|
-
import { H3 as
|
|
4
|
-
import
|
|
5
|
-
import { Icon as
|
|
6
|
-
import { jsx as o, jsxs as
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
var
|
|
14
|
-
const
|
|
15
|
-
return /* @__PURE__ */ o(
|
|
16
|
-
"aria-label":
|
|
1
|
+
import { useScreenSize as k } from "../hooks/useScreenSize.es.js";
|
|
2
|
+
import n from "@mui/material/Stack";
|
|
3
|
+
import { H3 as S, P as j } from "@mxenabled/mxui";
|
|
4
|
+
import f from "@mui/material/Button";
|
|
5
|
+
import { Icon as M } from "@mxenabled/mx-icons";
|
|
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($, {
|
|
16
|
+
"aria-label": c,
|
|
17
17
|
"aria-labelledby": "modal-title",
|
|
18
18
|
maxWidth: "xs",
|
|
19
|
-
onClose:
|
|
20
|
-
open:
|
|
19
|
+
onClose: m,
|
|
20
|
+
open: u,
|
|
21
21
|
role: "dialog",
|
|
22
22
|
sx: {
|
|
23
23
|
"& .MuiDialogContent-root": { p: 0 },
|
|
24
|
-
...
|
|
24
|
+
...I && { "& .MuiDialog-paper": { minWidth: "100%" } }
|
|
25
25
|
},
|
|
26
|
-
children: /* @__PURE__ */ o(
|
|
27
|
-
onSubmit: (
|
|
28
|
-
|
|
26
|
+
children: /* @__PURE__ */ o(B, { children: /* @__PURE__ */ t("form", {
|
|
27
|
+
onSubmit: (e) => {
|
|
28
|
+
e.preventDefault(), d || s();
|
|
29
29
|
},
|
|
30
30
|
children: [
|
|
31
|
-
/* @__PURE__ */
|
|
31
|
+
/* @__PURE__ */ t(n, {
|
|
32
32
|
sx: {
|
|
33
33
|
alignItems: "center",
|
|
34
34
|
flexDirection: "row",
|
|
@@ -39,46 +39,52 @@ var O = ({ closeAriaLabel: d, content: f, inputLabel: t, inputValue: i, isOpen:
|
|
|
39
39
|
pr: 16,
|
|
40
40
|
pt: 24
|
|
41
41
|
},
|
|
42
|
-
children: [/* @__PURE__ */
|
|
43
|
-
|
|
44
|
-
children:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
children: [/* @__PURE__ */ t(n, {
|
|
43
|
+
sx: { gap: 4 },
|
|
44
|
+
children: [/* @__PURE__ */ o(S, {
|
|
45
|
+
id: "modal-title",
|
|
46
|
+
children: c
|
|
47
|
+
}), y]
|
|
48
|
+
}), /* @__PURE__ */ o(F, {
|
|
49
|
+
"aria-label": h,
|
|
50
|
+
onClick: m,
|
|
48
51
|
sx: {
|
|
49
52
|
minHeight: 24,
|
|
50
53
|
position: "absolute",
|
|
51
54
|
right: 8,
|
|
52
55
|
top: 18
|
|
53
56
|
},
|
|
54
|
-
children: /* @__PURE__ */ o(
|
|
57
|
+
children: /* @__PURE__ */ o(M, {
|
|
55
58
|
name: "close",
|
|
56
59
|
sx: { color: "action.active" }
|
|
57
60
|
})
|
|
58
61
|
})]
|
|
59
62
|
}),
|
|
60
|
-
/* @__PURE__ */
|
|
63
|
+
/* @__PURE__ */ t(n, {
|
|
61
64
|
sx: {
|
|
62
65
|
gap: 24,
|
|
63
66
|
px: 24
|
|
64
67
|
},
|
|
65
|
-
children: [/* @__PURE__ */ o(
|
|
68
|
+
children: [/* @__PURE__ */ o(j, {
|
|
66
69
|
variant: "subtitle1",
|
|
67
|
-
children:
|
|
68
|
-
}),
|
|
70
|
+
children: g
|
|
71
|
+
}), r && /* @__PURE__ */ o(A, {
|
|
69
72
|
autoFocus: !0,
|
|
73
|
+
error: !!a,
|
|
74
|
+
helperText: a,
|
|
70
75
|
inputMode: "decimal",
|
|
71
|
-
label:
|
|
72
|
-
onChange: ({ target: { value:
|
|
73
|
-
/^\d*\.?\d*$/.test(
|
|
76
|
+
label: r,
|
|
77
|
+
onChange: ({ target: { value: e } }) => {
|
|
78
|
+
/^\d*\.?\d*$/.test(e) && b?.(e);
|
|
74
79
|
},
|
|
75
80
|
slotProps: {
|
|
76
|
-
input: { startAdornment: /* @__PURE__ */ o(
|
|
81
|
+
input: { startAdornment: /* @__PURE__ */ o(w, {
|
|
77
82
|
position: "start",
|
|
78
83
|
children: "$"
|
|
79
84
|
}) },
|
|
85
|
+
formHelperText: { role: "alert" },
|
|
80
86
|
htmlInput: {
|
|
81
|
-
"aria-label":
|
|
87
|
+
"aria-label": r,
|
|
82
88
|
noValidate: !0,
|
|
83
89
|
pattern: "[0-9]*\\.?[0-9]*"
|
|
84
90
|
}
|
|
@@ -87,25 +93,25 @@ var O = ({ closeAriaLabel: d, content: f, inputLabel: t, inputValue: i, isOpen:
|
|
|
87
93
|
value: i
|
|
88
94
|
})]
|
|
89
95
|
}),
|
|
90
|
-
/* @__PURE__ */
|
|
96
|
+
/* @__PURE__ */ t(H, {
|
|
91
97
|
sx: {
|
|
92
98
|
justifyContent: "flex-end",
|
|
93
99
|
gap: 16,
|
|
94
100
|
p: 24,
|
|
95
101
|
">:not(style)~:not(style)": { ml: 0 }
|
|
96
102
|
},
|
|
97
|
-
children: [l && /* @__PURE__ */ o(
|
|
103
|
+
children: [l && /* @__PURE__ */ o(f, {
|
|
98
104
|
"aria-label": l,
|
|
99
|
-
color:
|
|
100
|
-
onClick:
|
|
105
|
+
color: v,
|
|
106
|
+
onClick: C,
|
|
101
107
|
children: l
|
|
102
|
-
}), /* @__PURE__ */ o(
|
|
103
|
-
"aria-label":
|
|
104
|
-
color:
|
|
105
|
-
disabled:
|
|
106
|
-
onClick:
|
|
108
|
+
}), /* @__PURE__ */ o(f, {
|
|
109
|
+
"aria-label": p,
|
|
110
|
+
color: D,
|
|
111
|
+
disabled: d,
|
|
112
|
+
onClick: s,
|
|
107
113
|
variant: "contained",
|
|
108
|
-
children:
|
|
114
|
+
children: p
|
|
109
115
|
})]
|
|
110
116
|
})
|
|
111
117
|
]
|
|
@@ -113,7 +119,7 @@ var O = ({ closeAriaLabel: d, content: f, inputLabel: t, inputValue: i, isOpen:
|
|
|
113
119
|
});
|
|
114
120
|
};
|
|
115
121
|
export {
|
|
116
|
-
|
|
122
|
+
U as default
|
|
117
123
|
};
|
|
118
124
|
|
|
119
125
|
//# sourceMappingURL=CurrencyDialog.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrencyDialog.es.js","names":[],"sources":["../../../src/common/components/CurrencyDialog.tsx"],"sourcesContent":["import { 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 content?: string\n inputLabel?: string\n inputValue?: string\n isOpen: 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 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 inputLabel,\n inputValue,\n isOpen,\n handleInputChange,\n handleModalClose,\n handlePrimaryAction,\n handleSecondaryAction,\n primaryColor = 'primary',\n primaryText,\n secondaryColor = 'primary',\n secondaryText,\n title,\n}: CurrencyDialogProps) => {\n const numericValue = parseFloat(inputValue ?? '0')\n const isValid = inputValue !== '' && inputValue !== '0' && !isNaN(numericValue)\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 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 <H3 id=\"modal-title\">{title}</H3>\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 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 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={
|
|
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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"}
|
package/dist/core/index.es.js
CHANGED
|
@@ -1,138 +1,140 @@
|
|
|
1
1
|
import { LOCALES as r, VALID_LOCALES as t, buildDynamicCopy as i, getLocale as m } from "./utils/Localization.es.js";
|
|
2
2
|
import { Fetch as p } from "./utils/Fetch.es.js";
|
|
3
|
-
import { AccountIcon as
|
|
3
|
+
import { AccountIcon as f, AccountIconVariants as a, AccountSubType as c, AccountType as s, AccountTypeName as S, ConnectionStatus as A, ConnectionStatusEnums as u, ErrorStatuses as y, MfaStatuses as T, NonConnectedStatuses as l, ProcessingStatuses as g, PropertyType as d, PropertyTypeName as C, StatusName as N } from "./types/Account.es.js";
|
|
4
4
|
import { UserVerification as b } from "./types/Beat.es.js";
|
|
5
5
|
import { ExpenseStatus as B, ScheduledPaymentTypes as L } from "./types/Expense.es.js";
|
|
6
6
|
import { GoalType as E, MetaType as I, TrackType as P } from "./types/Goal.es.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
7
|
+
import { slot as F } from "./types/Insights.es.js";
|
|
8
|
+
import { AccountNotificationTypes as M, BudgetNotificationTypes as U, InsightNotificationTypes as V, NotificationTypes as x } from "./types/Notification.es.js";
|
|
9
|
+
import { TransactionStatus as W, TransactionType as k } from "./types/Transaction.es.js";
|
|
10
|
+
import { ScreenSize as w } from "./types/ScreenSize.es.js";
|
|
11
|
+
import { Frequency as _, RecurrenceStatus as j, RecurrenceType as v, RepeatingType as J } from "./types/RepeatingTransaction.es.js";
|
|
12
|
+
import { AccountApi as Q } from "./api/AccountApi.es.js";
|
|
13
|
+
import { AnalyticsApi as Y } from "./api/AnalyticsApi.es.js";
|
|
14
|
+
import { AppDataApi as $ } from "./api/AppDataApi.es.js";
|
|
15
|
+
import { BannerApi as ro } from "./api/BannerApi.es.js";
|
|
16
|
+
import { BeatApi as io } from "./api/BeatApi.es.js";
|
|
17
|
+
import { BudgetsApi as eo } from "./api/BudgetsApi.es.js";
|
|
18
|
+
import { CategoryApi as no } from "./api/CategoryApi.es.js";
|
|
19
|
+
import { FinstrongApi as ao } from "./api/FinstrongApi.es.js";
|
|
20
|
+
import { GlobalCopyApi as so } from "./api/GlobalCopyApi.es.js";
|
|
21
|
+
import { GoalApi as Ao } from "./api/GoalApi.es.js";
|
|
22
|
+
import { HelpApi as yo } from "./api/HelpApi.es.js";
|
|
23
|
+
import { HoldingApi as lo } from "./api/HoldingApi.es.js";
|
|
24
|
+
import { MerchantApi as Co } from "./api/MerchantApi.es.js";
|
|
25
|
+
import { NotificationApi as ho } from "./api/NotificationApi.es.js";
|
|
26
|
+
import { RepeatingTransactionsApi as Go } from "./api/RepeatingTransactionsApi.es.js";
|
|
27
|
+
import { ScheduledPaymentsApi as Lo } from "./api/ScheduledPaymentsApi.es.js";
|
|
28
|
+
import { SettingsApi as Eo } from "./api/SettingsApi.es.js";
|
|
29
|
+
import { TransactionApi as Po } from "./api/TransactionApi.es.js";
|
|
30
|
+
import { UserApi as Fo } from "./api/UserApi.es.js";
|
|
31
|
+
import { WidgetApi as Mo } from "./api/WidgetApi.es.js";
|
|
32
|
+
import { AccountStore as Vo } from "./stores/AccountStore.es.js";
|
|
33
|
+
import { AppDataStore as Oo } from "./stores/AppDataStore.es.js";
|
|
34
|
+
import { AnalyticsStore as ko } from "./stores/AnalyticsStore.es.js";
|
|
35
|
+
import { BeatStore as wo } from "./stores/BeatStore.es.js";
|
|
36
|
+
import { BudgetsStore as _o } from "./stores/BudgetsStore.es.js";
|
|
37
|
+
import { CashflowStore as vo } from "./stores/CashflowStore.es.js";
|
|
38
|
+
import { CategoryStore as Ko } from "./stores/CategoryStore.es.js";
|
|
39
|
+
import { ConnectStore as Xo } from "./stores/ConnectStore.es.js";
|
|
40
|
+
import { DebtsStore as Zo } from "./stores/DebtsStore.es.js";
|
|
41
|
+
import { FinstrongStore as or } from "./stores/FinstrongStore.es.js";
|
|
42
|
+
import { GlobalStore as tr } from "./stores/GlobalStore.es.js";
|
|
43
|
+
import { GlobalUiStore as mr } from "./stores/GlobalUiStore.es.js";
|
|
44
|
+
import { GlobalCopyStore as pr } from "./stores/GlobalCopyStore.es.js";
|
|
45
|
+
import { GoalStore as fr } from "./stores/GoalStore.es.js";
|
|
46
|
+
import { HelpStore as cr } from "./stores/HelpStore.es.js";
|
|
47
|
+
import { HoldingStore as Sr } from "./stores/HoldingStore.es.js";
|
|
48
|
+
import { InsightsV2Store as ur } from "./stores/InsightsV2Store.es.js";
|
|
49
|
+
import { MerchantStore as Tr } from "./stores/MerchantStore.es.js";
|
|
50
|
+
import { NetWorthStore as gr } from "./stores/NetWorthStore.es.js";
|
|
51
|
+
import { NotificationStore as Cr } from "./stores/NotificationStore.es.js";
|
|
52
|
+
import { RecurringTransactionsStore as hr } from "./stores/RecurringTransactionsStore.es.js";
|
|
53
|
+
import { SettingsStore as Gr } from "./stores/SettingsStore.es.js";
|
|
54
|
+
import { TransactionStore as Lr } from "./stores/TransactionStore.es.js";
|
|
55
|
+
import { TrendsStore as Er } from "./stores/TrendsStore.es.js";
|
|
56
|
+
import { UserStore as Pr } from "./stores/UserStore.es.js";
|
|
56
57
|
export {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
Q as AccountApi,
|
|
59
|
+
f as AccountIcon,
|
|
60
|
+
a as AccountIconVariants,
|
|
61
|
+
M as AccountNotificationTypes,
|
|
62
|
+
Vo as AccountStore,
|
|
62
63
|
c as AccountSubType,
|
|
63
64
|
s as AccountType,
|
|
64
65
|
S as AccountTypeName,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
66
|
+
Y as AnalyticsApi,
|
|
67
|
+
ko as AnalyticsStore,
|
|
68
|
+
$ as AppDataApi,
|
|
69
|
+
Oo as AppDataStore,
|
|
70
|
+
ro as BannerApi,
|
|
71
|
+
io as BeatApi,
|
|
72
|
+
wo as BeatStore,
|
|
73
|
+
U as BudgetNotificationTypes,
|
|
74
|
+
eo as BudgetsApi,
|
|
75
|
+
_o as BudgetsStore,
|
|
76
|
+
vo as CashflowStore,
|
|
77
|
+
no as CategoryApi,
|
|
78
|
+
Ko as CategoryStore,
|
|
79
|
+
Xo as ConnectStore,
|
|
79
80
|
A as ConnectionStatus,
|
|
80
81
|
u as ConnectionStatusEnums,
|
|
81
|
-
|
|
82
|
+
Zo as DebtsStore,
|
|
82
83
|
y as ErrorStatuses,
|
|
83
84
|
B as ExpenseStatus,
|
|
84
85
|
p as Fetch,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
ao as FinstrongApi,
|
|
87
|
+
or as FinstrongStore,
|
|
88
|
+
_ as Frequency,
|
|
89
|
+
so as GlobalCopyApi,
|
|
90
|
+
pr as GlobalCopyStore,
|
|
91
|
+
tr as GlobalStore,
|
|
92
|
+
mr as GlobalUiStore,
|
|
93
|
+
Ao as GoalApi,
|
|
94
|
+
fr as GoalStore,
|
|
94
95
|
E as GoalType,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
yo as HelpApi,
|
|
97
|
+
cr as HelpStore,
|
|
98
|
+
lo as HoldingApi,
|
|
99
|
+
Sr as HoldingStore,
|
|
100
|
+
V as InsightNotificationTypes,
|
|
101
|
+
ur as InsightsV2Store,
|
|
101
102
|
r as LOCALES,
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
Co as MerchantApi,
|
|
104
|
+
Tr as MerchantStore,
|
|
104
105
|
I as MetaType,
|
|
105
106
|
T as MfaStatuses,
|
|
106
|
-
|
|
107
|
+
gr as NetWorthStore,
|
|
107
108
|
l as NonConnectedStatuses,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
ho as NotificationApi,
|
|
110
|
+
Cr as NotificationStore,
|
|
111
|
+
x as NotificationTypes,
|
|
111
112
|
g as ProcessingStatuses,
|
|
112
113
|
d as PropertyType,
|
|
113
114
|
C as PropertyTypeName,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
j as RecurrenceStatus,
|
|
116
|
+
v as RecurrenceType,
|
|
117
|
+
hr as RecurringTransactionsStore,
|
|
118
|
+
Go as RepeatingTransactionsApi,
|
|
119
|
+
J as RepeatingType,
|
|
119
120
|
L as ScheduledPaymentTypes,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
Lo as ScheduledPaymentsApi,
|
|
122
|
+
w as ScreenSize,
|
|
123
|
+
Eo as SettingsApi,
|
|
124
|
+
Gr as SettingsStore,
|
|
124
125
|
N as StatusName,
|
|
125
126
|
P as TrackType,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
Po as TransactionApi,
|
|
128
|
+
W as TransactionStatus,
|
|
129
|
+
Lr as TransactionStore,
|
|
130
|
+
k as TransactionType,
|
|
131
|
+
Er as TrendsStore,
|
|
132
|
+
Fo as UserApi,
|
|
133
|
+
Pr as UserStore,
|
|
133
134
|
b as UserVerification,
|
|
134
135
|
t as VALID_LOCALES,
|
|
135
|
-
|
|
136
|
+
Mo as WidgetApi,
|
|
136
137
|
i as buildDynamicCopy,
|
|
137
|
-
m as getLocale
|
|
138
|
+
m as getLocale,
|
|
139
|
+
F as slot
|
|
138
140
|
};
|
|
@@ -39,7 +39,7 @@ export interface InsightsPayload {
|
|
|
39
39
|
widget_type: WidgetType;
|
|
40
40
|
instance_slot: InstanceSlot;
|
|
41
41
|
/**
|
|
42
|
-
* V1 only. The v2 contract carries everything a block needs on `instance_slot.
|
|
42
|
+
* V1 only. The v2 contract carries everything a block needs on `instance_slot.data`,
|
|
43
43
|
* and omits this key entirely (see the LargeTransactionV2 payload). Blocks that still require it
|
|
44
44
|
* get it as a required field through `BlockProps`, which re-declares it.
|
|
45
45
|
*/
|
|
@@ -237,22 +237,39 @@ export interface InstanceSlotRow {
|
|
|
237
237
|
primary_text?: string;
|
|
238
238
|
secondary_text?: string;
|
|
239
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* V2: the slots a block's variant filled, keyed by slot name; ditto owns the names and omits any
|
|
242
|
+
* slot it has no value for (`lib/ditto/blocks/<block>.yml`). Read with `slot()`, which names the
|
|
243
|
+
* kind the caller expects.
|
|
244
|
+
*/
|
|
245
|
+
export interface InstanceSlotData {
|
|
246
|
+
[slot: string]: unknown;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Reads one slot off a block's `data`; undefined when ditto did not fill it.
|
|
250
|
+
*
|
|
251
|
+
* The caller names the kind, because the slot's kind lives in the block's ditto schema and not
|
|
252
|
+
* here — a block fills slots with whatever its card needs, so no fixed list of kinds would hold
|
|
253
|
+
* (`account_switch_block` alone carries a boolean and `budget_block` a nested object).
|
|
254
|
+
*/
|
|
255
|
+
export declare const slot: <T = unknown>(data: InstanceSlotData | undefined, name: string) => T | undefined;
|
|
256
|
+
/**
|
|
257
|
+
* V2: which block renders this beat's content, and what it renders.
|
|
258
|
+
*
|
|
259
|
+
* `block` is optional: a beat whose template has no ditto config arrives as an empty `{}` and the
|
|
260
|
+
* card renders its copy and CTAs alone, so a reader cannot assume a block is named. One interface
|
|
261
|
+
* with `block` optional rather than a union with `Record<string, never>`, which TypeScript absorbs
|
|
262
|
+
* — that union left `block` reading as required and typed a promise it did not keep.
|
|
263
|
+
*
|
|
264
|
+
* `variant` is optional for the same reason — the empty `{}` carries neither. Every ditto beat
|
|
265
|
+
* file that names a block also names a variant, so a *filled* slot always has one; ditto drops a
|
|
266
|
+
* nil variant rather than sending null, which is why the type is `string | null | undefined`.
|
|
267
|
+
*/
|
|
240
268
|
export interface InstanceSlot {
|
|
241
|
-
block
|
|
242
|
-
variant
|
|
243
|
-
/**
|
|
244
|
-
|
|
245
|
-
* `instance_slot_with_header` envelopes (e.g. `"July 26"`, the transaction date).
|
|
246
|
-
*
|
|
247
|
-
* This is *not* a row field: under `with_header` a row's `secondary_text` is the category, so
|
|
248
|
-
* the header has to come from here. Absent on the `logos_only` envelopes (micro/notification).
|
|
249
|
-
*/
|
|
250
|
-
header_text?: string;
|
|
251
|
-
/**
|
|
252
|
-
* V2 (LargeTransactionV2 onward): rows carried inline on the slot. V1 blocks read their data
|
|
253
|
-
* from `InsightsPayload.instance_slot_data` instead and leave this absent.
|
|
254
|
-
*/
|
|
255
|
-
data_series?: InstanceSlotRow[];
|
|
269
|
+
block?: BlockType;
|
|
270
|
+
variant?: string | null;
|
|
271
|
+
/** The slots this block's variant declares in ditto. */
|
|
272
|
+
data?: InstanceSlotData;
|
|
256
273
|
/** Primary line on the hero card, e.g. "Epic Bank Checking, *1234". */
|
|
257
274
|
account_name?: string;
|
|
258
275
|
/** Secondary line beneath the name, e.g. "Checking Account" / "Credit Card". */
|
|
@@ -0,0 +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 // TODO: Add in_description_cta to insights_payload from backend\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\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 SaveExtraBlock: 'save_extra_block',\n StepChartBlock: 'step_chart_block',\n SVGImageBlock: 'svg_image_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}\n"],"mappings":"AA2RA,IAAa,IAAA,CACX,GACA,MACkB,IAAO,CAAA"}
|
|
@@ -13,7 +13,8 @@ export type { Expense } from './Expense';
|
|
|
13
13
|
export { ExpenseStatus, ScheduledPaymentTypes } from './Expense';
|
|
14
14
|
export type { DynamicCopyElement, GlobalCopy } from './GlobalCopy';
|
|
15
15
|
export { GoalType, MetaType, TrackType } from './Goal';
|
|
16
|
-
export type { ThemedSVGImageProps, DrilldownData, DrilldownPayload, InsightsPayload, InstanceSlot, Pill, WidgetType, InstanceSlotRow, BlockType, Description, PrimaryCTA, CtaPostMessageMetadata, SecondaryCTA, Subtitle, Footer, Logo, LogoRef, CategoryLogo, MerchantLogo, InstitutionLogo, Legends, } from './Insights';
|
|
16
|
+
export type { ThemedSVGImageProps, DrilldownData, DrilldownPayload, InsightsPayload, InstanceSlot, InstanceSlotData, Pill, WidgetType, InstanceSlotRow, BlockType, Description, PrimaryCTA, CtaPostMessageMetadata, SecondaryCTA, Subtitle, Footer, Logo, LogoRef, CategoryLogo, MerchantLogo, InstitutionLogo, Legends, } from './Insights';
|
|
17
|
+
export { slot } from './Insights';
|
|
17
18
|
export type { Goal, MonthlyCashFlowProfile, RetirementGoalAccount } from './Goal';
|
|
18
19
|
export type { Debt } from './Debt';
|
|
19
20
|
export type { GlobalCaptureException, GlobalErrorHandler, GlobalEventHandler } from './Handlers';
|