@mx-cartographer/experiences 9.4.12 → 9.4.14
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 +11 -0
- package/dist/common/utils/Theme.es.js +37 -37
- package/dist/common/utils/Theme.es.js.map +1 -1
- package/dist/core/types/AppData.d.ts +9 -8
- package/dist/core/types/Client.d.ts +19 -19
- package/dist/core/types/InsightsInstanceSlotData.d.ts +12 -1
- package/dist/core/types/InsightsInstanceSlotData.es.js.map +1 -1
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/TransactionDetailsBlock.d.ts +13 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/TransactionDetailsBlock.es.js +24 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/TransactionDetailsBlock.es.js.map +1 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/index.d.ts +3 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/transactionDetailsActions.d.ts +3 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/transactionDetailsActions.es.js +18 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/transactionDetailsActions.es.js.map +1 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.d.ts +31 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js +16 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js.map +1 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.d.ts +15 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.es.js +13 -0
- package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.es.js.map +1 -0
- package/dist/insights-v2/mappings/blocks.es.js +25 -18
- package/dist/insights-v2/mappings/blocks.es.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## [9.4.14] - 09-03-2026
|
|
2
|
+
|
|
3
|
+
- **ADDED** - insights-v2 `TransactionDetailsBlock` action block: shared drawer content any transaction beat opens via `primary_cta.block = 'TransactionDetailsBlock'`. Resolves its subject transaction from `instance_slot_data.transaction_guid`, then `beat.primary_transaction_guid`, then `transaction_guids[0]`, preferring the `transactionStore` object over the payload snapshot so inline edits write through; maps backend action-name strings to the `TopActions`/`BottomActions` enums (unknown names dropped, `undefined` means defaults, `[]` means none); `useTransactionDetailsPrepare` loads transaction data at drawer-open time. Registered in `mappings/blocks.ts`, with a Storybook story (WEC-1499)
|
|
4
|
+
- **ADDED** - `TransactionDetailsBlockData` to the insights-v2 instance-slot-data union (WEC-1499)
|
|
5
|
+
- **FIXED** - `TransactionDetailsBlock` no longer falls back to `beat.primary_transaction` when it is a snapshot of a *different* transaction than the resolved guid — previously a beat naming its subject via `instance_slot_data` whose guid missed in the store rendered the wrong transaction's details, and inline edits were made against the wrong subject (WEC-1499)
|
|
6
|
+
|
|
7
|
+
## [9.4.13] - 09-02-2026
|
|
8
|
+
|
|
9
|
+
- **CHANGED** - the theme shape radius is half of `card_corner_radius`, so cards render at 2x the theme radius per MXUI convention (MEW-3445)
|
|
10
|
+
- **CHANGED** - `StyleConfig.corner_radius` replaced by `card_corner_radius` and `button_corner_radius`, matching `ClientStyleProfile` (MEW-3445)
|
|
11
|
+
|
|
1
12
|
## [9.4.12] - 09-02-2026
|
|
2
13
|
|
|
3
14
|
- **CHANGED** - insights-v2 action drilldown refactor for readability: `InsightsV2Store`'s action drawer now carries an opaque `context` envelope (read via the new `useActionContext<T>()` hook) instead of block-specific fields, opened through a single generic `openActionDrawer`; added a `createVariantBlock` factory for variant→component dispatch with an unknown-variant fallback, and simplified `MakeTransferActionBlock`/`layout.ts` (WEC-1774)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { alpha as h, darken as
|
|
2
|
-
var
|
|
1
|
+
import { alpha as h, darken as b, lighten as v } from "@mui/material";
|
|
2
|
+
var M = [
|
|
3
3
|
"fontFamily",
|
|
4
4
|
"h1",
|
|
5
5
|
"h2",
|
|
@@ -11,7 +11,7 @@ var x = [
|
|
|
11
11
|
"subtitle1",
|
|
12
12
|
"subtitle2",
|
|
13
13
|
"tiny"
|
|
14
|
-
],
|
|
14
|
+
], O = [
|
|
15
15
|
{
|
|
16
16
|
key: "primary",
|
|
17
17
|
override: "primary_color",
|
|
@@ -48,23 +48,23 @@ var x = [
|
|
|
48
48
|
light: "success_color",
|
|
49
49
|
dark: "success_color_dark"
|
|
50
50
|
}
|
|
51
|
-
],
|
|
51
|
+
], R = [...O, {
|
|
52
52
|
key: "grey",
|
|
53
53
|
override: "neutral_color",
|
|
54
54
|
light: "neutral_color",
|
|
55
55
|
dark: "neutral_color_dark"
|
|
56
|
-
}],
|
|
57
|
-
const
|
|
58
|
-
for (const { key: k, override:
|
|
59
|
-
const
|
|
60
|
-
|
|
56
|
+
}], $ = (r, t, a, d) => {
|
|
57
|
+
const i = t === "dark", s = d ?? r?.mode ?? t, e = {};
|
|
58
|
+
for (const { key: k, override: C, light: f, dark: x } of R) {
|
|
59
|
+
const y = a?.[C] ?? r?.[i ? x : f];
|
|
60
|
+
y && (e[k] = y);
|
|
61
61
|
}
|
|
62
|
-
const
|
|
62
|
+
const _ = i && s !== "browser", p = (k) => _ ? { dark: k } : { light: k }, n = a?.background_color ?? r?.background_color, c = a?.paper_color ?? r?.paper_color;
|
|
63
63
|
(n || c) && (e.background = {
|
|
64
|
-
...n && { default:
|
|
65
|
-
...c && { paper:
|
|
64
|
+
...n && { default: p(n) },
|
|
65
|
+
...c && { paper: p(c) }
|
|
66
66
|
});
|
|
67
|
-
const o = a?.font_name || r?.body_font_name || r?.system_font, u = a?.header_font_name || r?.header_font_name, l = a?.use_glass ?? r?.use_glass, m = a?.
|
|
67
|
+
const o = a?.font_name || r?.body_font_name || r?.system_font, u = a?.header_font_name || r?.header_font_name, l = a?.use_glass ?? r?.use_glass, m = a?.card_corner_radius ?? r?.card_corner_radius, g = m !== void 0 ? m / 2 : void 0;
|
|
68
68
|
return {
|
|
69
69
|
...Object.keys(e).length > 0 && { paletteOptions: e },
|
|
70
70
|
...(o || u) && { typographyOptions: {
|
|
@@ -72,18 +72,18 @@ var x = [
|
|
|
72
72
|
...u && { headerFontFamily: u }
|
|
73
73
|
} },
|
|
74
74
|
...l !== void 0 && { styleOptions: { useGlass: l } },
|
|
75
|
-
...
|
|
75
|
+
...g !== void 0 && { shapeOptions: { borderRadius: g } }
|
|
76
76
|
};
|
|
77
|
-
},
|
|
78
|
-
const
|
|
77
|
+
}, w = (r, t, a) => {
|
|
78
|
+
const d = a?.master?.style, i = {
|
|
79
79
|
MuiTabs: { styleOverrides: { indicator: { backgroundColor: r.palette.primary.light } } },
|
|
80
80
|
MuiPickersCalendarHeader: { styleOverrides: { switchViewButton: {
|
|
81
81
|
color: r.palette.primary.lighter,
|
|
82
82
|
"&:hover": { backgroundColor: h(r.palette.primary.light, 0.1) }
|
|
83
83
|
} } }
|
|
84
|
-
}, s = t?.button_corner_radius, e =
|
|
84
|
+
}, s = d?.button_corner_radius ?? t?.button_corner_radius, e = d?.card_corner_radius ?? t?.card_corner_radius;
|
|
85
85
|
return { components: {
|
|
86
|
-
...
|
|
86
|
+
...i,
|
|
87
87
|
...s !== void 0 && {
|
|
88
88
|
MuiButton: { styleOverrides: { root: {
|
|
89
89
|
borderRadius: `${s}px`,
|
|
@@ -104,21 +104,21 @@ var x = [
|
|
|
104
104
|
MuiPaper: { styleOverrides: { rounded: { borderRadius: `${e}px` } } }
|
|
105
105
|
}
|
|
106
106
|
} };
|
|
107
|
-
},
|
|
108
|
-
const a = t === "dark",
|
|
109
|
-
for (const { key:
|
|
110
|
-
const
|
|
111
|
-
|
|
107
|
+
}, F = (r, t) => {
|
|
108
|
+
const a = t === "dark", d = {};
|
|
109
|
+
for (const { key: i, light: s, dark: e } of R) {
|
|
110
|
+
const _ = r?.[a ? e : s];
|
|
111
|
+
_ && (d[i] = _);
|
|
112
112
|
}
|
|
113
|
-
return
|
|
114
|
-
},
|
|
115
|
-
const
|
|
116
|
-
lighter:
|
|
117
|
-
light:
|
|
113
|
+
return d;
|
|
114
|
+
}, B = (r, t, a) => {
|
|
115
|
+
const d = r.palette.mode === "dark", i = (a?.master?.style?.font_name || t?.body_font_name || t?.system_font) ?? r.typography.fontFamily, s = (o, u) => o ? {
|
|
116
|
+
lighter: v(o, 0.5),
|
|
117
|
+
light: v(o, 0.25),
|
|
118
118
|
main: o,
|
|
119
|
-
dark:
|
|
120
|
-
darker:
|
|
121
|
-
} : u, e = Object.fromEntries(
|
|
119
|
+
dark: b(o, 0.25),
|
|
120
|
+
darker: b(o, 0.5)
|
|
121
|
+
} : u, e = Object.fromEntries(O.map(({ key: o, light: u, dark: l }) => [o, s(t?.[d ? l : u], r.palette[o])])), _ = Object.fromEntries(M.map((o) => [o, o === "fontFamily" ? i : { fontFamily: i }])), p = {
|
|
122
122
|
MuiTabs: { styleOverrides: { indicator: { backgroundColor: e.primary.light } } },
|
|
123
123
|
MuiPickersCalendarHeader: { styleOverrides: { switchViewButton: {
|
|
124
124
|
color: e.primary.lighter,
|
|
@@ -126,10 +126,10 @@ var x = [
|
|
|
126
126
|
} } }
|
|
127
127
|
}, n = t?.button_corner_radius, c = t?.card_corner_radius;
|
|
128
128
|
return {
|
|
129
|
-
typography:
|
|
129
|
+
typography: _,
|
|
130
130
|
palette: e,
|
|
131
131
|
components: {
|
|
132
|
-
...
|
|
132
|
+
...p,
|
|
133
133
|
...n && {
|
|
134
134
|
MuiButton: { styleOverrides: { root: {
|
|
135
135
|
borderRadius: `${n}px`,
|
|
@@ -151,10 +151,10 @@ var x = [
|
|
|
151
151
|
};
|
|
152
152
|
};
|
|
153
153
|
export {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
w as getClientComponentOverrides,
|
|
155
|
+
$ as getClientCustomizations,
|
|
156
|
+
F as getClientPaletteOptions,
|
|
157
|
+
B as getClientTheme
|
|
158
158
|
};
|
|
159
159
|
|
|
160
160
|
//# sourceMappingURL=Theme.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Theme.es.js","names":[],"sources":["../../../src/common/utils/Theme.ts"],"sourcesContent":["import { alpha, darken, lighten, PaletteColor, PaletteMode, Theme } from '@mui/material'\nimport type { Customizations } from '@mxenabled/mxui'\n\nimport type { ClientStyleProfile } from '../../core'\nimport { ClientConfig, StyleConfig } from '../../core/types/AppData'\n\ntype PaletteOptions = NonNullable<Customizations['paletteOptions']>\ntype ModeColorOptions = Partial<NonNullable<NonNullable<PaletteOptions['background']>['default']>>\n\nconst TYPOGRAPHY_VARIANTS = [\n 'fontFamily',\n 'h1',\n 'h2',\n 'h3',\n 'body1',\n 'body2',\n 'button',\n 'caption',\n 'subtitle1',\n 'subtitle2',\n 'tiny',\n] as const\n\nconst PALETTE_CONFIG = [\n { key: 'primary', override: 'primary_color', light: 'primary_color', dark: 'primary_color_dark' },\n {\n key: 'secondary',\n override: 'secondary_color',\n light: 'secondary_color',\n dark: 'secondary_color_dark',\n },\n { key: 'error', override: 'error_color', light: 'error_color', dark: 'error_color_dark' },\n { key: 'warning', override: 'warning_color', light: 'warning_color', dark: 'warning_color_dark' },\n { key: 'info', override: 'info_color', light: 'info_color', dark: 'info_color_dark' },\n { key: 'success', override: 'success_color', light: 'success_color', dark: 'success_color_dark' },\n] as const\n\nconst SEED_CONFIG = [\n ...PALETTE_CONFIG,\n { key: 'grey', override: 'neutral_color', light: 'neutral_color', dark: 'neutral_color_dark' },\n] as const\n\nexport const getClientCustomizations = (\n clientStyleProfile: ClientStyleProfile,\n mode: PaletteMode,\n styleConfig?: StyleConfig,\n requestedMode?: ClientStyleProfile['mode'],\n): Customizations => {\n const isDark = mode === 'dark'\n const requested = requestedMode ?? clientStyleProfile?.mode ?? mode\n\n const paletteOptions: PaletteOptions = {}\n for (const { key, override, light, dark } of SEED_CONFIG) {\n const color = styleConfig?.[override] ?? clientStyleProfile?.[isDark ? dark : light]\n if (color) paletteOptions[key] = color\n }\n\n const useDarkSlot = isDark && requested !== 'browser'\n const asModeColor = (color: string): ModeColorOptions =>\n useDarkSlot ? { dark: color } : { light: color }\n const backgroundColor = styleConfig?.background_color ?? clientStyleProfile?.background_color\n const paperColor = styleConfig?.paper_color ?? clientStyleProfile?.paper_color\n if (backgroundColor || paperColor) {\n paletteOptions.background = {\n ...(backgroundColor && { default: asModeColor(backgroundColor) }),\n ...(paperColor && { paper: asModeColor(paperColor) }),\n } as PaletteOptions['background']\n }\n\n const fontFamily =\n styleConfig?.font_name || clientStyleProfile?.body_font_name || clientStyleProfile?.system_font\n const headerFontFamily = styleConfig?.header_font_name || clientStyleProfile?.header_font_name\n\n const useGlass = styleConfig?.use_glass ?? clientStyleProfile?.use_glass\n const borderRadius = styleConfig?.corner_radius ?? clientStyleProfile?.card_corner_radius\n\n return {\n ...(Object.keys(paletteOptions).length > 0 && { paletteOptions }),\n ...((fontFamily || headerFontFamily) && {\n typographyOptions: {\n ...(fontFamily && { fontFamily }),\n ...(headerFontFamily && { headerFontFamily }),\n },\n }),\n ...(useGlass !== undefined && { styleOptions: { useGlass } }),\n ...(borderRadius !== undefined && { shapeOptions: { borderRadius } }),\n }\n}\n\nexport const getClientComponentOverrides = (\n theme: Theme,\n clientStyleProfile: ClientStyleProfile,\n clientConfig?: ClientConfig,\n) => {\n const styleConfig = clientConfig?.master?.style\n\n const baseComponents = {\n MuiTabs: {\n styleOverrides: {\n indicator: { backgroundColor: theme.palette.primary.light },\n },\n },\n MuiPickersCalendarHeader: {\n styleOverrides: {\n switchViewButton: {\n color: theme.palette.primary.lighter,\n '&:hover': { backgroundColor: alpha(theme.palette.primary.light, 0.1) },\n },\n },\n },\n }\n\n const buttonRadius = clientStyleProfile?.button_corner_radius\n const cardRadius = styleConfig?.corner_radius ?? clientStyleProfile?.card_corner_radius\n\n const components = {\n ...baseComponents,\n ...(buttonRadius !== undefined && {\n MuiButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n MuiIconButton: {\n styleOverrides: {\n root: {\n borderRadius: `${buttonRadius}px`,\n minWidth: buttonRadius,\n minHeight: buttonRadius,\n },\n },\n },\n MuiToggleButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n }),\n ...(cardRadius !== undefined && {\n MuiCard: {\n styleOverrides: { root: { borderRadius: `${cardRadius}px` } },\n },\n MuiPaper: {\n styleOverrides: {\n rounded: { borderRadius: `${cardRadius}px` },\n },\n },\n }),\n }\n\n return { components }\n}\n\n/** @deprecated Use `getClientCustomizations` and pass the result to `createMXTheme` */\nexport const getClientPaletteOptions = (\n clientStyleProfile: ClientStyleProfile,\n mode: PaletteMode,\n): Record<string, string> => {\n const isDark = mode === 'dark'\n const options: Record<string, string> = {}\n\n for (const { key, light, dark } of SEED_CONFIG) {\n const color = clientStyleProfile?.[isDark ? dark : light] as string | undefined\n if (color) options[key] = color\n }\n\n return options\n}\n\n/** @deprecated Build the theme with `getClientCustomizations` + `createMXTheme` and merge `getClientComponentOverrides` on top */\nexport const getClientTheme = (\n theme: Theme,\n clientStyleProfile: ClientStyleProfile,\n clientConfig?: ClientConfig,\n) => {\n const isDark = theme.palette.mode === 'dark'\n const font =\n (clientConfig?.master?.style?.font_name ||\n clientStyleProfile?.body_font_name ||\n clientStyleProfile?.system_font) ??\n theme.typography.fontFamily\n\n const generatePalette = (color: string | undefined, defaultColor: PaletteColor) =>\n color\n ? {\n lighter: lighten(color, 0.5),\n light: lighten(color, 0.25),\n main: color,\n dark: darken(color, 0.25),\n darker: darken(color, 0.5),\n }\n : defaultColor\n\n const palette = Object.fromEntries(\n PALETTE_CONFIG.map(({ key, light, dark }) => [\n key,\n generatePalette(\n clientStyleProfile?.[isDark ? dark : light] as string | undefined,\n theme.palette[key],\n ),\n ]),\n )\n\n const typography = Object.fromEntries(\n TYPOGRAPHY_VARIANTS.map((variant) => [\n variant,\n variant === 'fontFamily' ? font : { fontFamily: font },\n ]),\n )\n\n const baseComponents = {\n MuiTabs: {\n styleOverrides: {\n indicator: { backgroundColor: palette.primary.light },\n },\n },\n MuiPickersCalendarHeader: {\n styleOverrides: {\n switchViewButton: {\n color: palette.primary.lighter,\n '&:hover': { backgroundColor: alpha(palette.primary.light, 0.1) },\n },\n },\n },\n }\n\n const buttonRadius = clientStyleProfile?.button_corner_radius\n const cardRadius = clientStyleProfile?.card_corner_radius\n\n const components = {\n ...baseComponents,\n ...(buttonRadius && {\n MuiButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n MuiIconButton: {\n styleOverrides: {\n root: {\n borderRadius: `${buttonRadius}px`,\n minWidth: buttonRadius,\n minHeight: buttonRadius,\n },\n },\n },\n MuiToggleButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n }),\n ...(cardRadius && {\n MuiCard: {\n styleOverrides: { root: { borderRadius: `${cardRadius}px` } },\n },\n }),\n ...(cardRadius && {\n MuiPaper: {\n styleOverrides: {\n rounded: { borderRadius: `${cardRadius}px` },\n },\n },\n }),\n }\n\n return { typography, palette, components }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Theme.es.js","names":[],"sources":["../../../src/common/utils/Theme.ts"],"sourcesContent":["import { alpha, darken, lighten, PaletteColor, PaletteMode, Theme } from '@mui/material'\nimport type { Customizations } from '@mxenabled/mxui'\n\nimport type { ClientStyleProfile } from '../../core'\nimport { ClientConfig, StyleConfig } from '../../core/types/AppData'\n\ntype PaletteOptions = NonNullable<Customizations['paletteOptions']>\ntype ModeColorOptions = Partial<NonNullable<NonNullable<PaletteOptions['background']>['default']>>\n\nconst TYPOGRAPHY_VARIANTS = [\n 'fontFamily',\n 'h1',\n 'h2',\n 'h3',\n 'body1',\n 'body2',\n 'button',\n 'caption',\n 'subtitle1',\n 'subtitle2',\n 'tiny',\n] as const\n\nconst PALETTE_CONFIG = [\n { key: 'primary', override: 'primary_color', light: 'primary_color', dark: 'primary_color_dark' },\n {\n key: 'secondary',\n override: 'secondary_color',\n light: 'secondary_color',\n dark: 'secondary_color_dark',\n },\n { key: 'error', override: 'error_color', light: 'error_color', dark: 'error_color_dark' },\n { key: 'warning', override: 'warning_color', light: 'warning_color', dark: 'warning_color_dark' },\n { key: 'info', override: 'info_color', light: 'info_color', dark: 'info_color_dark' },\n { key: 'success', override: 'success_color', light: 'success_color', dark: 'success_color_dark' },\n] as const\n\nconst SEED_CONFIG = [\n ...PALETTE_CONFIG,\n { key: 'grey', override: 'neutral_color', light: 'neutral_color', dark: 'neutral_color_dark' },\n] as const\n\nexport const getClientCustomizations = (\n clientStyleProfile: ClientStyleProfile,\n mode: PaletteMode,\n styleConfig?: StyleConfig,\n requestedMode?: ClientStyleProfile['mode'],\n): Customizations => {\n const isDark = mode === 'dark'\n const requested = requestedMode ?? clientStyleProfile?.mode ?? mode\n\n const paletteOptions: PaletteOptions = {}\n for (const { key, override, light, dark } of SEED_CONFIG) {\n const color = styleConfig?.[override] ?? clientStyleProfile?.[isDark ? dark : light]\n if (color) paletteOptions[key] = color\n }\n\n const useDarkSlot = isDark && requested !== 'browser'\n const asModeColor = (color: string): ModeColorOptions =>\n useDarkSlot ? { dark: color } : { light: color }\n const backgroundColor = styleConfig?.background_color ?? clientStyleProfile?.background_color\n const paperColor = styleConfig?.paper_color ?? clientStyleProfile?.paper_color\n if (backgroundColor || paperColor) {\n paletteOptions.background = {\n ...(backgroundColor && { default: asModeColor(backgroundColor) }),\n ...(paperColor && { paper: asModeColor(paperColor) }),\n } as PaletteOptions['background']\n }\n\n const fontFamily =\n styleConfig?.font_name || clientStyleProfile?.body_font_name || clientStyleProfile?.system_font\n const headerFontFamily = styleConfig?.header_font_name || clientStyleProfile?.header_font_name\n\n const useGlass = styleConfig?.use_glass ?? clientStyleProfile?.use_glass\n const cardRadius = styleConfig?.card_corner_radius ?? clientStyleProfile?.card_corner_radius\n // Cards render at 2x the shape token (MXUI's defaults: token 4, Paper 8), so the\n // client's card radius is halved here and applied at full value to MuiCard/MuiPaper\n // via getClientComponentOverrides\n const borderRadius = cardRadius !== undefined ? cardRadius / 2 : undefined\n\n return {\n ...(Object.keys(paletteOptions).length > 0 && { paletteOptions }),\n ...((fontFamily || headerFontFamily) && {\n typographyOptions: {\n ...(fontFamily && { fontFamily }),\n ...(headerFontFamily && { headerFontFamily }),\n },\n }),\n ...(useGlass !== undefined && { styleOptions: { useGlass } }),\n ...(borderRadius !== undefined && { shapeOptions: { borderRadius } }),\n }\n}\n\nexport const getClientComponentOverrides = (\n theme: Theme,\n clientStyleProfile: ClientStyleProfile,\n clientConfig?: ClientConfig,\n) => {\n const styleConfig = clientConfig?.master?.style\n\n const baseComponents = {\n MuiTabs: {\n styleOverrides: {\n indicator: { backgroundColor: theme.palette.primary.light },\n },\n },\n MuiPickersCalendarHeader: {\n styleOverrides: {\n switchViewButton: {\n color: theme.palette.primary.lighter,\n '&:hover': { backgroundColor: alpha(theme.palette.primary.light, 0.1) },\n },\n },\n },\n }\n\n const buttonRadius = styleConfig?.button_corner_radius ?? clientStyleProfile?.button_corner_radius\n const cardRadius = styleConfig?.card_corner_radius ?? clientStyleProfile?.card_corner_radius\n\n const components = {\n ...baseComponents,\n ...(buttonRadius !== undefined && {\n MuiButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n MuiIconButton: {\n styleOverrides: {\n root: {\n borderRadius: `${buttonRadius}px`,\n minWidth: buttonRadius,\n minHeight: buttonRadius,\n },\n },\n },\n MuiToggleButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n }),\n ...(cardRadius !== undefined && {\n MuiCard: {\n styleOverrides: { root: { borderRadius: `${cardRadius}px` } },\n },\n MuiPaper: {\n styleOverrides: {\n rounded: { borderRadius: `${cardRadius}px` },\n },\n },\n }),\n }\n\n return { components }\n}\n\n/** @deprecated Use `getClientCustomizations` and pass the result to `createMXTheme` */\nexport const getClientPaletteOptions = (\n clientStyleProfile: ClientStyleProfile,\n mode: PaletteMode,\n): Record<string, string> => {\n const isDark = mode === 'dark'\n const options: Record<string, string> = {}\n\n for (const { key, light, dark } of SEED_CONFIG) {\n const color = clientStyleProfile?.[isDark ? dark : light] as string | undefined\n if (color) options[key] = color\n }\n\n return options\n}\n\n/** @deprecated Build the theme with `getClientCustomizations` + `createMXTheme` and merge `getClientComponentOverrides` on top */\nexport const getClientTheme = (\n theme: Theme,\n clientStyleProfile: ClientStyleProfile,\n clientConfig?: ClientConfig,\n) => {\n const isDark = theme.palette.mode === 'dark'\n const font =\n (clientConfig?.master?.style?.font_name ||\n clientStyleProfile?.body_font_name ||\n clientStyleProfile?.system_font) ??\n theme.typography.fontFamily\n\n const generatePalette = (color: string | undefined, defaultColor: PaletteColor) =>\n color\n ? {\n lighter: lighten(color, 0.5),\n light: lighten(color, 0.25),\n main: color,\n dark: darken(color, 0.25),\n darker: darken(color, 0.5),\n }\n : defaultColor\n\n const palette = Object.fromEntries(\n PALETTE_CONFIG.map(({ key, light, dark }) => [\n key,\n generatePalette(\n clientStyleProfile?.[isDark ? dark : light] as string | undefined,\n theme.palette[key],\n ),\n ]),\n )\n\n const typography = Object.fromEntries(\n TYPOGRAPHY_VARIANTS.map((variant) => [\n variant,\n variant === 'fontFamily' ? font : { fontFamily: font },\n ]),\n )\n\n const baseComponents = {\n MuiTabs: {\n styleOverrides: {\n indicator: { backgroundColor: palette.primary.light },\n },\n },\n MuiPickersCalendarHeader: {\n styleOverrides: {\n switchViewButton: {\n color: palette.primary.lighter,\n '&:hover': { backgroundColor: alpha(palette.primary.light, 0.1) },\n },\n },\n },\n }\n\n const buttonRadius = clientStyleProfile?.button_corner_radius\n const cardRadius = clientStyleProfile?.card_corner_radius\n\n const components = {\n ...baseComponents,\n ...(buttonRadius && {\n MuiButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n MuiIconButton: {\n styleOverrides: {\n root: {\n borderRadius: `${buttonRadius}px`,\n minWidth: buttonRadius,\n minHeight: buttonRadius,\n },\n },\n },\n MuiToggleButton: {\n styleOverrides: {\n root: { borderRadius: `${buttonRadius}px`, textTransform: 'none' },\n },\n },\n }),\n ...(cardRadius && {\n MuiCard: {\n styleOverrides: { root: { borderRadius: `${cardRadius}px` } },\n },\n }),\n ...(cardRadius && {\n MuiPaper: {\n styleOverrides: {\n rounded: { borderRadius: `${cardRadius}px` },\n },\n },\n }),\n }\n\n return { typography, palette, components }\n}\n"],"mappings":"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"}
|
|
@@ -49,20 +49,21 @@ export interface MasterConfig {
|
|
|
49
49
|
}
|
|
50
50
|
export interface StyleConfig {
|
|
51
51
|
background_color?: string;
|
|
52
|
+
button_corner_radius?: number;
|
|
53
|
+
card_corner_radius?: number;
|
|
54
|
+
error_color?: string;
|
|
55
|
+
font_name?: string;
|
|
56
|
+
header_font_name?: string;
|
|
57
|
+
info_color?: string;
|
|
58
|
+
neutral_color?: string;
|
|
52
59
|
paper_color?: string;
|
|
53
60
|
primary_color?: string;
|
|
54
61
|
secondary_color?: string;
|
|
55
62
|
success_color?: string;
|
|
56
|
-
error_color?: string;
|
|
57
|
-
warning_color?: string;
|
|
58
|
-
info_color?: string;
|
|
59
|
-
neutral_color?: string;
|
|
60
|
-
corner_radius?: number;
|
|
61
|
-
font_name?: string;
|
|
62
|
-
header_font_name?: string;
|
|
63
63
|
use_body_font_url?: boolean;
|
|
64
|
-
use_header_font_url?: boolean;
|
|
65
64
|
use_glass?: boolean;
|
|
65
|
+
use_header_font_url?: boolean;
|
|
66
|
+
warning_color?: string;
|
|
66
67
|
}
|
|
67
68
|
export interface DeepLinkParams {
|
|
68
69
|
account_guids?: string[];
|
|
@@ -96,30 +96,30 @@ export interface ClientInsightProfile {
|
|
|
96
96
|
is_recurring_transactions_manager_enabled: boolean;
|
|
97
97
|
}
|
|
98
98
|
export interface ClientStyleProfile {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
background_color?: string;
|
|
100
|
+
body_font_name?: string;
|
|
101
|
+
body_font_url?: string;
|
|
102
|
+
button_corner_radius?: number;
|
|
103
|
+
card_corner_radius?: number;
|
|
104
104
|
error_color?: string;
|
|
105
|
-
|
|
105
|
+
error_color_dark?: string;
|
|
106
|
+
header_font_name?: string;
|
|
107
|
+
header_font_url?: string;
|
|
106
108
|
info_color?: string;
|
|
109
|
+
info_color_dark?: string;
|
|
110
|
+
mode?: 'dark' | 'light' | 'browser';
|
|
111
|
+
neutral_color?: string;
|
|
112
|
+
neutral_color_dark?: string;
|
|
113
|
+
paper_color?: string;
|
|
114
|
+
primary_color?: string;
|
|
107
115
|
primary_color_dark?: string;
|
|
116
|
+
primary_font_regular?: string;
|
|
117
|
+
secondary_color?: string;
|
|
108
118
|
secondary_color_dark?: string;
|
|
109
|
-
|
|
119
|
+
success_color?: string;
|
|
110
120
|
success_color_dark?: string;
|
|
111
|
-
error_color_dark?: string;
|
|
112
|
-
warning_color_dark?: string;
|
|
113
|
-
info_color_dark?: string;
|
|
114
|
-
mode?: 'dark' | 'light' | 'browser';
|
|
115
121
|
system_font?: string;
|
|
116
|
-
card_corner_radius?: number;
|
|
117
|
-
button_corner_radius?: number;
|
|
118
|
-
background_color?: string;
|
|
119
|
-
paper_color?: string;
|
|
120
|
-
body_font_name?: string;
|
|
121
|
-
body_font_url?: string;
|
|
122
|
-
header_font_name?: string;
|
|
123
|
-
header_font_url?: string;
|
|
124
122
|
use_glass?: boolean;
|
|
123
|
+
warning_color?: string;
|
|
124
|
+
warning_color_dark?: string;
|
|
125
125
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataSeries, Legends } from '../../core';
|
|
2
2
|
import { Transaction } from './Transaction';
|
|
3
|
-
export interface InsightsInstanceSlotData extends Partial<BarChartBlockData>, Partial<BudgetBlockData>, Partial<DonutChartBlockData>, Partial<DoubleProgressBarBlockData>, Partial<ImageBlockData>, Partial<AccountBlockData>, Partial<SaveExtraBlockData>, Partial<StepChartBlockData>, Partial<SVGImageBlockData>, Partial<CategoryTransactionsBlockData>, Partial<AccountSwitchBlockData>, Partial<CommonProps> {
|
|
3
|
+
export interface InsightsInstanceSlotData extends Partial<BarChartBlockData>, Partial<BudgetBlockData>, Partial<DonutChartBlockData>, Partial<DoubleProgressBarBlockData>, Partial<ImageBlockData>, Partial<AccountBlockData>, Partial<SaveExtraBlockData>, Partial<StepChartBlockData>, Partial<SVGImageBlockData>, Partial<CategoryTransactionsBlockData>, Partial<AccountSwitchBlockData>, Partial<TransactionDetailsBlockData>, Partial<CommonProps> {
|
|
4
4
|
}
|
|
5
5
|
interface CommonProps {
|
|
6
6
|
amount?: number;
|
|
@@ -122,4 +122,15 @@ export type InsightTransaction = Pick<Transaction, 'amount'> & Partial<Pick<Tran
|
|
|
122
122
|
export interface CategoryTransactionsBlockData {
|
|
123
123
|
primary_transaction?: InsightTransaction;
|
|
124
124
|
}
|
|
125
|
+
export interface TransactionDetailsBlockData {
|
|
126
|
+
/**
|
|
127
|
+
* Explicit subject of the details drawer. Optional: the block falls back to
|
|
128
|
+
* `beat.primary_transaction_guid`, then `beat.transaction_guids[0]`.
|
|
129
|
+
*/
|
|
130
|
+
transaction_guid?: string;
|
|
131
|
+
/** `TopActions` member names, e.g. `['Category', 'Date', 'Memo']`. Omit for the defaults. */
|
|
132
|
+
top_actions?: string[];
|
|
133
|
+
/** `BottomActions` member names, e.g. `['MerchantBudget', 'HideTransaction']`. Omit for defaults. */
|
|
134
|
+
bottom_actions?: string[];
|
|
135
|
+
}
|
|
125
136
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InsightsInstanceSlotData.es.js","names":[],"sources":["../../../src/core/types/InsightsInstanceSlotData.ts"],"sourcesContent":["import type { DataSeries, Legends } from '../../core'\nimport type { Transaction } from './Transaction'\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<CategoryTransactionsBlockData>,\n Partial<AccountSwitchBlockData>,\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 legends?: (Legends | LegendProps)[]\n category_guid?: string\n data_series?: DataSeries | DataSet[]\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\nexport interface AccountSwitchBlockData {\n discovered_institution_guid: string\n discovered_institution_name: string\n held_institution_guid: string\n held_institution_name: string\n is_connected: boolean\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\nexport type InsightTransaction = Pick<Transaction, 'amount'> &\n Partial<Pick<Transaction, 'category_guid' | 'date' | 'description' | 'merchant_guid'>> & {\n merchant_name?: string\n }\n\nexport interface CategoryTransactionsBlockData {\n primary_transaction?: InsightTransaction\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"InsightsInstanceSlotData.es.js","names":[],"sources":["../../../src/core/types/InsightsInstanceSlotData.ts"],"sourcesContent":["import type { DataSeries, Legends } from '../../core'\nimport type { Transaction } from './Transaction'\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<CategoryTransactionsBlockData>,\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 legends?: (Legends | LegendProps)[]\n category_guid?: string\n data_series?: DataSeries | DataSet[]\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\nexport interface AccountSwitchBlockData {\n discovered_institution_guid: string\n discovered_institution_name: string\n held_institution_guid: string\n held_institution_name: string\n is_connected: boolean\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\nexport type InsightTransaction = Pick<Transaction, 'amount'> &\n Partial<Pick<Transaction, 'category_guid' | 'date' | 'description' | 'merchant_guid'>> & {\n merchant_name?: string\n }\n\nexport interface CategoryTransactionsBlockData {\n primary_transaction?: InsightTransaction\n}\n\n// TransactionDetails Action Block\nexport interface TransactionDetailsBlockData {\n /**\n * Explicit subject of the details drawer. Optional: the block falls back to\n * `beat.primary_transaction_guid`, then `beat.transaction_guids[0]`.\n */\n transaction_guid?: string\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":"AAqIA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,kBAAA,OACA,EAAA,qBAAA,UACA,EAAA,wBAAA;AACF,GAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ActionBlockProps } from '../../mappings/blocks';
|
|
2
|
+
/**
|
|
3
|
+
* Single-transaction drawer content. The detail rendering and inline editing (category picker, date,
|
|
4
|
+
* memo, tags, split/hide/merchant-budget) all live in the shared `TransactionDetails` component from
|
|
5
|
+
* the transactions module — this block's job is only to resolve *which* transaction and *which*
|
|
6
|
+
* actions, then hand off.
|
|
7
|
+
*
|
|
8
|
+
* `observer` is required: the resolved transaction comes from TransactionStore, and `usePrepare` may
|
|
9
|
+
* still be loading it when this first renders. Without it the drawer would stay on the loader.
|
|
10
|
+
*/
|
|
11
|
+
export declare const TransactionDetailsBlock: (({ beat, }: ActionBlockProps) => import("react/jsx-runtime").JSX.Element) & {
|
|
12
|
+
displayName: string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useGlobalCopyStore as e } from "../../../common/context/hooks.es.js";
|
|
2
|
+
import s from "../../../common/components/Loader.es.js";
|
|
3
|
+
import c from "../../../transactions/components/shared/TransactionDetails.es.js";
|
|
4
|
+
import { useTransactionDetailsBlock as p } from "./useTransactionDetailsBlock.es.js";
|
|
5
|
+
import { observer as f } from "mobx-react-lite";
|
|
6
|
+
import l from "@mui/material/Stack";
|
|
7
|
+
import { Text as u } from "@mxenabled/mxui";
|
|
8
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
9
|
+
var v = f(function({ beat: t }) {
|
|
10
|
+
const { common: i } = e(), { bottomActions: n, isLoading: m, topActions: a, transaction: r } = p(t);
|
|
11
|
+
return m ? /* @__PURE__ */ o(s, {}) : r ? /* @__PURE__ */ o(c, {
|
|
12
|
+
bottomActions: n,
|
|
13
|
+
topActions: a,
|
|
14
|
+
transaction: r
|
|
15
|
+
}) : /* @__PURE__ */ o(l, {
|
|
16
|
+
sx: { p: 24 },
|
|
17
|
+
children: /* @__PURE__ */ o(u, { children: i.error_message })
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
export {
|
|
21
|
+
v as TransactionDetailsBlock
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=TransactionDetailsBlock.es.js.map
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/TransactionDetailsBlock.es.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransactionDetailsBlock.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionDetailsBlock/TransactionDetailsBlock.tsx"],"sourcesContent":["import Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\nimport { observer } from 'mobx-react-lite'\n\nimport { Loader, useGlobalCopyStore } from '../../../common'\nimport TransactionDetails from '../../../transactions/components/shared/TransactionDetails'\nimport type { ActionBlockProps } from '../../mappings/blocks'\n\nimport { useTransactionDetailsBlock } from './useTransactionDetailsBlock'\n\n/**\n * Single-transaction drawer content. The detail rendering and inline editing (category picker, date,\n * memo, tags, split/hide/merchant-budget) all live in the shared `TransactionDetails` component from\n * the transactions module — this block's job is only to resolve *which* transaction and *which*\n * actions, then hand off.\n *\n * `observer` is required: the resolved transaction comes from TransactionStore, and `usePrepare` may\n * still be loading it when this first renders. Without it the drawer would stay on the loader.\n */\nexport const TransactionDetailsBlock = observer(function TransactionDetailsBlock({\n beat,\n}: ActionBlockProps) {\n const { common: commonCopy } = useGlobalCopyStore()\n const { bottomActions, isLoading, topActions, transaction } = useTransactionDetailsBlock(beat)\n\n if (isLoading) return <Loader />\n\n // Loading finished and the guid still resolves to nothing — a stale beat pointing at a deleted or\n // out-of-window transaction. Mirrors ActionBlockLayer's unknown-block branch rather than rendering\n // an empty drawer.\n if (!transaction) {\n return (\n <Stack sx={{ p: 24 }}>\n <Text>{commonCopy.error_message}</Text>\n </Stack>\n )\n }\n\n return (\n <TransactionDetails\n bottomActions={bottomActions}\n topActions={topActions}\n transaction={transaction}\n />\n )\n})\n"],"mappings":";;;;;;;;AAoBA,IAAa,IAA0B,EAAS,SAAiC,EAC/E,MAAA,EAAA,GACmB;AACnB,QAAM,EAAE,QAAQ,EAAA,IAAe,EAAmB,GAC5C,EAAE,eAAA,GAAe,WAAA,GAAW,YAAA,GAAY,aAAA,EAAA,IAAgB,EAA2B,CAAI;AAE7F,SAAI,IAAkB,gBAAA,EAAC,GAAD,CAAS,CAAA,IAK1B,IASH,gBAAA,EAAC,GAAD;AAAA,IACiB,eAAA;AAAA,IACH,YAAA;AAAA,IACC,aAAA;AAAA,EACd,CAAA,IAXC,gBAAA,EAAC,GAAD;AAAA,IAAO,IAAI,EAAE,GAAG,GAAG;AAAA,IACjB,UAAA,gBAAA,EAAC,GAAD,EAAA,UAAO,EAAW,cAAoB,CAAA;AAAA,EACjC,CAAA;AAWb,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BottomActions as t, DEFAULT_BOTTOM_ACTIONS as i, DEFAULT_TOP_ACTIONS as c, TopActions as r } from "../../../transactions/constants/Actions.es.js";
|
|
2
|
+
var s = {
|
|
3
|
+
Category: r.Category,
|
|
4
|
+
Date: r.Date,
|
|
5
|
+
Memo: r.Memo,
|
|
6
|
+
Tags: r.Tags
|
|
7
|
+
}, A = {
|
|
8
|
+
MerchantBudget: t.MerchantBudget,
|
|
9
|
+
SplitTransaction: t.SplitTransaction,
|
|
10
|
+
HideTransaction: t.HideTransaction,
|
|
11
|
+
MerchantLogo: t.MerchantLogo
|
|
12
|
+
}, e = (o, T, n) => o ? o.map((a) => T[a]).filter((a) => a !== void 0) : n, O = (o) => e(o, s, c), _ = (o) => e(o, A, i);
|
|
13
|
+
export {
|
|
14
|
+
_ as resolveBottomActions,
|
|
15
|
+
O as resolveTopActions
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=transactionDetailsActions.es.js.map
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/transactionDetailsActions.es.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionDetailsActions.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionDetailsBlock/transactionDetailsActions.ts"],"sourcesContent":["import {\n BottomActions,\n DEFAULT_BOTTOM_ACTIONS,\n DEFAULT_TOP_ACTIONS,\n TopActions,\n} from '../../../transactions/constants/Actions'\n\n/**\n * The backend sends action names as strings on `instance_slot_data`; `TransactionDetails` takes the\n * numeric enums. Keep the lookup keyed by the enum's own member names so adding a member to\n * `Actions.ts` is picked up here without a second edit.\n *\n * Unknown names are dropped rather than throwing: a beat configured against a newer ditto config\n * than the bundle should render with the actions it *does* understand, not blow up the drawer.\n */\nconst TOP_ACTION_BY_NAME: Record<string, TopActions> = {\n Category: TopActions.Category,\n Date: TopActions.Date,\n Memo: TopActions.Memo,\n Tags: TopActions.Tags,\n}\n\nconst BOTTOM_ACTION_BY_NAME: Record<string, BottomActions> = {\n MerchantBudget: BottomActions.MerchantBudget,\n SplitTransaction: BottomActions.SplitTransaction,\n HideTransaction: BottomActions.HideTransaction,\n MerchantLogo: BottomActions.MerchantLogo,\n}\n\nconst resolve = <T>(names: string[] | undefined, lookup: Record<string, T>, fallback: T[]): T[] => {\n // `undefined` means \"not configured\" -> defaults. An explicit empty array means \"no actions\",\n // which is a legitimate per-beat choice (a read-only details view) and must not fall back.\n if (!names) return fallback\n\n return names.map((name) => lookup[name]).filter((action): action is T => action !== undefined)\n}\n\nexport const resolveTopActions = (names?: string[]): TopActions[] =>\n resolve(names, TOP_ACTION_BY_NAME, DEFAULT_TOP_ACTIONS)\n\nexport const resolveBottomActions = (names?: string[]): BottomActions[] =>\n resolve(names, BOTTOM_ACTION_BY_NAME, DEFAULT_BOTTOM_ACTIONS)\n"],"mappings":";AAeA,IAAM,IAAiD;AAAA,EACrD,UAAU,EAAW;AAAA,EACrB,MAAM,EAAW;AAAA,EACjB,MAAM,EAAW;AAAA,EACjB,MAAM,EAAW;AACnB,GAEM,IAAuD;AAAA,EAC3D,gBAAgB,EAAc;AAAA,EAC9B,kBAAkB,EAAc;AAAA,EAChC,iBAAiB,EAAc;AAAA,EAC/B,cAAc,EAAc;AAC9B,GAEM,IAAA,CAAc,GAA6B,GAA2B,MAGrE,IAEE,EAAM,IAAA,CAAK,MAAS,EAAO,CAAA,CAAK,EAAE,OAAA,CAAQ,MAAwB,MAAW,MAAS,IAF1E,GAKR,IAAA,CAAqB,MAChC,EAAQ,GAAO,GAAoB,CAAmB,GAE3C,IAAA,CAAwB,MACnC,EAAQ,GAAO,GAAuB,CAAsB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Beat, Transaction } from '../../../core';
|
|
2
|
+
import { BottomActions, TopActions } from '../../../transactions/constants/Actions';
|
|
3
|
+
interface TransactionDetailsBlockState {
|
|
4
|
+
bottomActions: BottomActions[];
|
|
5
|
+
/** True while the store is still loading; the block shows a loader instead of an empty state. */
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
topActions: TopActions[];
|
|
8
|
+
/** `undefined` once loading finishes means the transaction could not be resolved. */
|
|
9
|
+
transaction?: Transaction;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolves which transaction this drawer is about, and which inline actions it offers.
|
|
13
|
+
*
|
|
14
|
+
* Resolution order is deliberate:
|
|
15
|
+
* 1. `instance_slot_data.transaction_guid` — the beat explicitly naming its subject.
|
|
16
|
+
* 2. `beat.primary_transaction_guid` — the standard beat-level pointer.
|
|
17
|
+
* 3. `beat.transaction_guids[0]` — last resort for beats that only carry the list.
|
|
18
|
+
*
|
|
19
|
+
* The guid is then looked up in `transactionStore.detailedTransactions` rather than used directly,
|
|
20
|
+
* because `TransactionDetails` needs the *detailed* shape (account + category + taggings joined in)
|
|
21
|
+
* and edits must write through to the same store object the rest of the app renders. `buildDetailed
|
|
22
|
+
* Transactions` inside the store is this repo's equivalent of pulse's `buildTransactionDetails`.
|
|
23
|
+
*
|
|
24
|
+
* `beat.primary_transaction` is the fallback of last resort: it is a payload snapshot, not a store
|
|
25
|
+
* object, so inline edits against it would not propagate. Preferring it over a store hit would make
|
|
26
|
+
* editing silently no-op, which is why it is only used when the store genuinely has nothing — and
|
|
27
|
+
* only when it is a snapshot of the *same* transaction the guid resolved to (or when no guid
|
|
28
|
+
* resolved at all). A snapshot of some other transaction is not an answer to this question.
|
|
29
|
+
*/
|
|
30
|
+
export declare const useTransactionDetailsBlock: (beat: Beat) => TransactionDetailsBlockState;
|
|
31
|
+
export {};
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useTransactionStore as e } from "../../../common/context/hooks.es.js";
|
|
2
|
+
import { resolveBottomActions as p, resolveTopActions as m } from "./transactionDetailsActions.es.js";
|
|
3
|
+
var g = (o) => {
|
|
4
|
+
const { detailedTransactions: a, isTransactionDataLoaded: i } = e(), s = o.insights_payload?.instance_slot_data ?? {}, t = s.transaction_guid ?? o.primary_transaction_guid ?? o.transaction_guids?.[0], r = t ? a.find((d) => d.guid === t) : void 0, n = o.primary_transaction, c = !t || n?.guid === t;
|
|
5
|
+
return {
|
|
6
|
+
bottomActions: p(s.bottom_actions),
|
|
7
|
+
isLoading: !i,
|
|
8
|
+
topActions: m(s.top_actions),
|
|
9
|
+
transaction: r ?? (c ? n : void 0)
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
g as useTransactionDetailsBlock
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=useTransactionDetailsBlock.es.js.map
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.es.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTransactionDetailsBlock.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsBlock.ts"],"sourcesContent":["import { useTransactionStore } from '../../../common'\nimport type { Beat, Transaction } from '../../../core'\nimport type { TransactionDetailsBlockData } from '../../../core/types/InsightsInstanceSlotData'\nimport type { BottomActions, TopActions } from '../../../transactions/constants/Actions'\n\nimport { resolveBottomActions, resolveTopActions } from './transactionDetailsActions'\n\ninterface TransactionDetailsBlockState {\n bottomActions: BottomActions[]\n /** True while the store is still loading; the block shows a loader instead of an empty state. */\n isLoading: boolean\n topActions: TopActions[]\n /** `undefined` once loading finishes means the transaction could not be resolved. */\n transaction?: Transaction\n}\n\n/**\n * Resolves which transaction this drawer is about, and which inline actions it offers.\n *\n * Resolution order is deliberate:\n * 1. `instance_slot_data.transaction_guid` — the beat explicitly naming its subject.\n * 2. `beat.primary_transaction_guid` — the standard beat-level pointer.\n * 3. `beat.transaction_guids[0]` — last resort for beats that only carry the list.\n *\n * The guid is then looked up in `transactionStore.detailedTransactions` rather than used directly,\n * because `TransactionDetails` needs the *detailed* shape (account + category + taggings joined in)\n * and edits must write through to the same store object the rest of the app renders. `buildDetailed\n * Transactions` inside the store is this repo's equivalent of pulse's `buildTransactionDetails`.\n *\n * `beat.primary_transaction` is the fallback of last resort: it is a payload snapshot, not a store\n * object, so inline edits against it would not propagate. Preferring it over a store hit would make\n * editing silently no-op, which is why it is only used when the store genuinely has nothing — and\n * only when it is a snapshot of the *same* transaction the guid resolved to (or when no guid\n * resolved at all). A snapshot of some other transaction is not an answer to this question.\n */\nexport const useTransactionDetailsBlock = (beat: Beat): TransactionDetailsBlockState => {\n const { detailedTransactions, isTransactionDataLoaded } = useTransactionStore()\n\n const slotData = (beat.insights_payload?.instance_slot_data ?? {}) as TransactionDetailsBlockData\n\n const guid =\n slotData.transaction_guid ?? beat.primary_transaction_guid ?? beat.transaction_guids?.[0]\n\n const fromStore = guid\n ? detailedTransactions.find((transaction) => transaction.guid === guid)\n : undefined\n\n // The snapshot is only a valid answer for the guid we actually resolved. When a beat names its\n // subject via instance_slot_data (or transaction_guids[0]) and that guid misses in the store,\n // falling back unconditionally would render a *different* transaction's details — and inline\n // edits would then be made against the wrong subject. Match on guid, or accept the snapshot only\n // when no guid resolved at all.\n const snapshot = beat.primary_transaction\n const snapshotMatches = !guid || snapshot?.guid === guid\n\n return {\n bottomActions: resolveBottomActions(slotData.bottom_actions),\n isLoading: !isTransactionDataLoaded,\n topActions: resolveTopActions(slotData.top_actions),\n transaction: fromStore ?? (snapshotMatches ? snapshot : undefined),\n }\n}\n"],"mappings":";;AAmCA,IAAa,IAAA,CAA8B,MAA6C;AACtF,QAAM,EAAE,sBAAA,GAAsB,yBAAA,EAAA,IAA4B,EAAoB,GAExE,IAAY,EAAK,kBAAkB,sBAAsB,CAAC,GAE1D,IACJ,EAAS,oBAAoB,EAAK,4BAA4B,EAAK,oBAAoB,CAAA,GAEnF,IAAY,IACd,EAAqB,KAAA,CAAM,MAAgB,EAAY,SAAS,CAAI,IACpE,QAOE,IAAW,EAAK,qBAChB,IAAkB,CAAC,KAAQ,GAAU,SAAS;AAEpD,SAAO;AAAA,IACL,eAAe,EAAqB,EAAS,cAAc;AAAA,IAC3D,WAAW,CAAC;AAAA,IACZ,YAAY,EAAkB,EAAS,WAAW;AAAA,IAClD,aAAa,MAAc,IAAkB,IAAW;AAAA,EAC1D;AACF"}
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ActionBlockProps } from '../../mappings/blocks';
|
|
2
|
+
/**
|
|
3
|
+
* Open-time data guarantee for the transaction-details drawer. Wired as the block's `usePrepare`,
|
|
4
|
+
* so `ActionBlockLayer` runs it once each time a CTA opens the drawer (`ActionBlockRunner` mounts on
|
|
5
|
+
* open and unmounts on close).
|
|
6
|
+
*
|
|
7
|
+
* A beat can be rendered in a feed long before the transactions module has ever loaded — the feed
|
|
8
|
+
* does not depend on TransactionStore — so `detailedTransactions` is frequently empty at open time.
|
|
9
|
+
* `loadTransactionData` also pulls the accounts and categories that `buildDetailedTransactions`
|
|
10
|
+
* joins against, which is why it is preferred over the narrower `loadTransactions`.
|
|
11
|
+
*
|
|
12
|
+
* Guarded on `isTransactionDataLoaded` so re-opening the drawer does not refetch, and the store's
|
|
13
|
+
* own in-flight flags make a concurrent call a no-op.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useTransactionDetailsPrepare: (_props: ActionBlockProps) => void;
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.es.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useTransactionStore as r } from "../../../common/context/hooks.es.js";
|
|
2
|
+
import t from "react";
|
|
3
|
+
var n = (e) => {
|
|
4
|
+
const { isTransactionDataLoaded: a, loadTransactionData: o } = r();
|
|
5
|
+
t.useEffect(() => {
|
|
6
|
+
a || o();
|
|
7
|
+
}, []);
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
n as useTransactionDetailsPrepare
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=useTransactionDetailsPrepare.es.js.map
|
package/dist/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.es.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTransactionDetailsPrepare.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.ts"],"sourcesContent":["import React from 'react'\n\nimport { useTransactionStore } from '../../../common'\nimport type { ActionBlockProps } from '../../mappings/blocks'\n\n/**\n * Open-time data guarantee for the transaction-details drawer. Wired as the block's `usePrepare`,\n * so `ActionBlockLayer` runs it once each time a CTA opens the drawer (`ActionBlockRunner` mounts on\n * open and unmounts on close).\n *\n * A beat can be rendered in a feed long before the transactions module has ever loaded — the feed\n * does not depend on TransactionStore — so `detailedTransactions` is frequently empty at open time.\n * `loadTransactionData` also pulls the accounts and categories that `buildDetailedTransactions`\n * joins against, which is why it is preferred over the narrower `loadTransactions`.\n *\n * Guarded on `isTransactionDataLoaded` so re-opening the drawer does not refetch, and the store's\n * own in-flight flags make a concurrent call a no-op.\n */\nexport const useTransactionDetailsPrepare = (_props: ActionBlockProps) => {\n const { isTransactionDataLoaded, loadTransactionData } = useTransactionStore()\n\n React.useEffect(() => {\n if (!isTransactionDataLoaded) void loadTransactionData()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n}\n"],"mappings":";;AAkBA,IAAa,IAAA,CAAgC,MAA6B;AACxE,QAAM,EAAE,yBAAA,GAAyB,qBAAA,EAAA,IAAwB,EAAoB;AAE7E,EAAA,EAAM,UAAA,MAAgB;AACpB,IAAK,KAAyB,EAAyB;AAAA,EAEzD,GAAG,CAAC,CAAC;AACP"}
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import { BarchartBlock as e } from "../blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js";
|
|
2
2
|
import { DoubleBarChartBlock as a } from "../blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.es.js";
|
|
3
3
|
import c from "../blocks/ChartBlocks/StepChartBlock/StepChartBlock.es.js";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import l from "../blocks/ChartBlocks/DonutChartBlock/DonutChartBlock.es.js";
|
|
5
|
+
import m from "../blocks/ChartBlocks/DoubleProgressBarBlock/DoubleProgressBarBlock.es.js";
|
|
6
6
|
import i from "../blocks/ComponentBlocks/AccountBlock/AccountBlock.es.js";
|
|
7
7
|
import n from "../blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.es.js";
|
|
8
8
|
import { BudgetBlock as k } from "../blocks/ComponentBlocks/BudgetBlock/BudgetBlock.es.js";
|
|
9
|
-
import
|
|
10
|
-
import { CategoryTransactionsBlock as
|
|
11
|
-
import
|
|
12
|
-
import { SVGImageBlock as
|
|
9
|
+
import p from "../blocks/ComponentBlocks/SaveExtraBlock/SaveExtraBlock.es.js";
|
|
10
|
+
import { CategoryTransactionsBlock as s } from "../blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js";
|
|
11
|
+
import B from "../blocks/ImageBlocks/ImageBlock.es.js";
|
|
12
|
+
import { SVGImageBlock as f } from "../blocks/ImageBlocks/SVGImageBlock/SVGImageBlock.es.js";
|
|
13
13
|
import { PlaceholderActionBlock as u } from "../actionBlocks/PlaceholderActionBlock.es.js";
|
|
14
14
|
import { getMakeTransferDrawerTitle as h } from "../actionBlocks/MakeTransferActionBlock/layout.es.js";
|
|
15
15
|
import { MakeTransferActionBlockLayer as C } from "../actionBlocks/MakeTransferActionBlock/MakeTransferActionBlockLayer.es.js";
|
|
16
|
+
import { TransactionDetailsBlock as D } from "../actionBlocks/TransactionDetailsBlock/TransactionDetailsBlock.es.js";
|
|
17
|
+
import { useTransactionDetailsPrepare as T } from "../actionBlocks/TransactionDetailsBlock/useTransactionDetailsPrepare.es.js";
|
|
16
18
|
var t = (o) => {
|
|
17
19
|
}, _ = /* @__PURE__ */ new Set([
|
|
18
20
|
"",
|
|
19
21
|
"null",
|
|
20
22
|
"undefined"
|
|
21
|
-
]),
|
|
23
|
+
]), z = (o) => {
|
|
22
24
|
const r = o?.trim().toLowerCase();
|
|
23
25
|
return !!r && !_.has(r);
|
|
24
|
-
},
|
|
26
|
+
}, G = {
|
|
25
27
|
PlaceholderActionBlock: {
|
|
26
28
|
Component: u,
|
|
27
29
|
usePrepare: t,
|
|
@@ -31,25 +33,30 @@ var t = (o) => {
|
|
|
31
33
|
Component: C,
|
|
32
34
|
usePrepare: t,
|
|
33
35
|
title: h
|
|
36
|
+
},
|
|
37
|
+
TransactionDetailsBlock: {
|
|
38
|
+
Component: D,
|
|
39
|
+
usePrepare: T,
|
|
40
|
+
title: () => "Transaction Details"
|
|
34
41
|
}
|
|
35
|
-
},
|
|
42
|
+
}, K = {
|
|
36
43
|
AccountBlock: i,
|
|
37
44
|
account_switch_block: n,
|
|
38
45
|
BarChartBlock: e,
|
|
39
46
|
BudgetBlock: k,
|
|
40
|
-
CategoryTransactionsBlock:
|
|
41
|
-
DonutChartBlock:
|
|
47
|
+
CategoryTransactionsBlock: s,
|
|
48
|
+
DonutChartBlock: l,
|
|
42
49
|
DoubleBarChartBlock: a,
|
|
43
|
-
DoubleProgressBarBlock:
|
|
44
|
-
ImageBlock:
|
|
45
|
-
save_extra_block:
|
|
50
|
+
DoubleProgressBarBlock: m,
|
|
51
|
+
ImageBlock: B,
|
|
52
|
+
save_extra_block: p,
|
|
46
53
|
StepChartBlock: c,
|
|
47
|
-
SVGImageBlock:
|
|
54
|
+
SVGImageBlock: f
|
|
48
55
|
};
|
|
49
56
|
export {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
G as actionBlocks,
|
|
58
|
+
K as blocks,
|
|
59
|
+
z as hasDrawerBlock
|
|
53
60
|
};
|
|
54
61
|
|
|
55
62
|
//# sourceMappingURL=blocks.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.es.js","names":[],"sources":["../../../src/insights-v2/mappings/blocks.ts"],"sourcesContent":["import {\n AccountBlock,\n AccountSwitchBlock,\n BarchartBlock,\n BudgetBlock,\n CategoryTransactionsBlock,\n DonutChartBlock,\n DoubleBarChartBlock,\n DoubleProgressBarBlock,\n SaveExtraBlock,\n SVGImageBlock,\n} from '../blocks'\nimport StepChartBlock from '../blocks/ChartBlocks/StepChartBlock'\nimport ImageBlock from '../blocks/ImageBlocks/ImageBlock'\n\nimport type { Beat, GlobalCopy, InsightsPayload } from '../../core'\nimport { PlaceholderActionBlock } from '../actionBlocks/PlaceholderActionBlock'\nimport { MakeTransferActionBlockLayer } from '../actionBlocks/MakeTransferActionBlock/MakeTransferActionBlockLayer'\nimport { getMakeTransferDrawerTitle } from '../actionBlocks/MakeTransferActionBlock/layout'\n\n// Drilldown indexes are not passed down: action blocks read them from\n// InsightsV2Store (useInsightsV2Store().actionDrawer).\nexport interface ActionBlockProps {\n beat: Beat\n}\n\nconst noop = (_: ActionBlockProps) => {}\n\n// A CTA opens a drawer only when it carries a real `block`. The backend may send\n// an empty/absent block (or the literal strings \"null\"/\"undefined\") for CTAs\n// that trigger something else (e.g. a postMessage) instead of a drilldown.\nconst NON_BLOCK_VALUES = new Set(['', 'null', 'undefined'])\nexport const hasDrawerBlock = (block?: string | null): boolean => {\n const normalized = block?.trim().toLowerCase()\n return !!normalized && !NON_BLOCK_VALUES.has(normalized)\n}\n\nexport interface ActionBlockEntry {\n Component: React.ComponentType<ActionBlockProps>\n usePrepare: (props: ActionBlockProps) => void // required; default to noop in each entry\n // Resolves the drawer title from the clicked CTA's variant + copy (e.g.\n // MakeTransfer reads its variant title from layout.ts). Falls back to the CTA label.\n title?: (variant: string | null | undefined, copy: GlobalCopy) => string\n}\n\n// Registry of drawer drilldowns, keyed by the `block` name the backend sends\n// on a beat's CTA. To add one: create a component taking ActionBlockProps,\n// read the clicked indexes from useInsightsV2Store().actionDrawer, and\n// register it here. Add\n// `usePrepare` when the block needs to load data before rendering.\nexport const actionBlocks = {\n PlaceholderActionBlock: {\n Component: PlaceholderActionBlock,\n usePrepare: noop,\n title: () => 'Action Block Layer Drilldown',\n },\n make_transfer: {\n Component: MakeTransferActionBlockLayer,\n usePrepare: noop,\n title: getMakeTransferDrawerTitle,\n },\n} as Record<string, ActionBlockEntry>\n\nexport const blocks = {\n AccountBlock: AccountBlock,\n account_switch_block: AccountSwitchBlock,\n BarChartBlock: BarchartBlock,\n BudgetBlock: BudgetBlock,\n CategoryTransactionsBlock: CategoryTransactionsBlock,\n DonutChartBlock: DonutChartBlock,\n DoubleBarChartBlock: DoubleBarChartBlock,\n DoubleProgressBarBlock: DoubleProgressBarBlock,\n ImageBlock: ImageBlock,\n save_extra_block: SaveExtraBlock,\n StepChartBlock: StepChartBlock,\n SVGImageBlock: SVGImageBlock,\n} as Record<string, React.ComponentType<{ payload: InsightsPayload; beatGuid?: string }>>\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"blocks.es.js","names":[],"sources":["../../../src/insights-v2/mappings/blocks.ts"],"sourcesContent":["import {\n AccountBlock,\n AccountSwitchBlock,\n BarchartBlock,\n BudgetBlock,\n CategoryTransactionsBlock,\n DonutChartBlock,\n DoubleBarChartBlock,\n DoubleProgressBarBlock,\n SaveExtraBlock,\n SVGImageBlock,\n} from '../blocks'\nimport StepChartBlock from '../blocks/ChartBlocks/StepChartBlock'\nimport ImageBlock from '../blocks/ImageBlocks/ImageBlock'\n\nimport type { Beat, GlobalCopy, InsightsPayload } from '../../core'\nimport { PlaceholderActionBlock } from '../actionBlocks/PlaceholderActionBlock'\nimport { MakeTransferActionBlockLayer } from '../actionBlocks/MakeTransferActionBlock/MakeTransferActionBlockLayer'\nimport { getMakeTransferDrawerTitle } from '../actionBlocks/MakeTransferActionBlock/layout'\nimport {\n TransactionDetailsBlock,\n useTransactionDetailsPrepare,\n} from '../actionBlocks/TransactionDetailsBlock'\n\n// Drilldown indexes are not passed down: action blocks read them from\n// InsightsV2Store (useInsightsV2Store().actionDrawer).\nexport interface ActionBlockProps {\n beat: Beat\n}\n\nconst noop = (_: ActionBlockProps) => {}\n\n// A CTA opens a drawer only when it carries a real `block`. The backend may send\n// an empty/absent block (or the literal strings \"null\"/\"undefined\") for CTAs\n// that trigger something else (e.g. a postMessage) instead of a drilldown.\nconst NON_BLOCK_VALUES = new Set(['', 'null', 'undefined'])\nexport const hasDrawerBlock = (block?: string | null): boolean => {\n const normalized = block?.trim().toLowerCase()\n return !!normalized && !NON_BLOCK_VALUES.has(normalized)\n}\n\nexport interface ActionBlockEntry {\n Component: React.ComponentType<ActionBlockProps>\n usePrepare: (props: ActionBlockProps) => void // required; default to noop in each entry\n // Resolves the drawer title from the clicked CTA's variant + copy (e.g.\n // MakeTransfer reads its variant title from layout.ts). Falls back to the CTA label.\n title?: (variant: string | null | undefined, copy: GlobalCopy) => string\n}\n\n// Registry of drawer drilldowns, keyed by the `block` name the backend sends\n// on a beat's CTA. To add one: create a component taking ActionBlockProps,\n// read the clicked indexes from useInsightsV2Store().actionDrawer, and\n// register it here. Add\n// `usePrepare` when the block needs to load data before rendering.\nexport const actionBlocks = {\n PlaceholderActionBlock: {\n Component: PlaceholderActionBlock,\n usePrepare: noop,\n title: () => 'Action Block Layer Drilldown',\n },\n make_transfer: {\n Component: MakeTransferActionBlockLayer,\n usePrepare: noop,\n title: getMakeTransferDrawerTitle,\n },\n TransactionDetailsBlock: {\n Component: TransactionDetailsBlock,\n usePrepare: useTransactionDetailsPrepare,\n title: () => 'Transaction Details',\n },\n} as Record<string, ActionBlockEntry>\n\nexport const blocks = {\n AccountBlock: AccountBlock,\n account_switch_block: AccountSwitchBlock,\n BarChartBlock: BarchartBlock,\n BudgetBlock: BudgetBlock,\n CategoryTransactionsBlock: CategoryTransactionsBlock,\n DonutChartBlock: DonutChartBlock,\n DoubleBarChartBlock: DoubleBarChartBlock,\n DoubleProgressBarBlock: DoubleProgressBarBlock,\n ImageBlock: ImageBlock,\n save_extra_block: SaveExtraBlock,\n StepChartBlock: StepChartBlock,\n SVGImageBlock: SVGImageBlock,\n} as Record<string, React.ComponentType<{ payload: InsightsPayload; beatGuid?: string }>>\n"],"mappings":";;;;;;;;;;;;;;;;;AA8BA,IAAM,IAAA,CAAQ,MAAwB;AAAC,GAKjC,IAAmB,oBAAI,IAAI;AAAA,EAAC;AAAA,EAAI;AAAA,EAAQ;AAAW,CAAC,GAC7C,IAAA,CAAkB,MAAmC;AAChE,QAAM,IAAa,GAAO,KAAK,EAAE,YAAY;AAC7C,SAAO,CAAC,CAAC,KAAc,CAAC,EAAiB,IAAI,CAAU;AACzD,GAea,IAAe;AAAA,EAC1B,wBAAwB;AAAA,IACtB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAA,MAAa;AAAA,EACf;AAAA,EACA,eAAe;AAAA,IACb,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EACA,yBAAyB;AAAA,IACvB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,OAAA,MAAa;AAAA,EACf;AACF,GAEa,IAAS;AAAA,EACN,cAAA;AAAA,EACd,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACF,aAAA;AAAA,EACc,2BAAA;AAAA,EACV,iBAAA;AAAA,EACI,qBAAA;AAAA,EACG,wBAAA;AAAA,EACZ,YAAA;AAAA,EACZ,kBAAkB;AAAA,EACF,gBAAA;AAAA,EACD,eAAA;AACjB"}
|