@mx-cartographer/experiences 9.7.104 → 9.7.106
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 +8 -0
- package/dist/common/utils/AccountFilter.d.ts +0 -14
- package/dist/common/utils/AccountFilter.es.js.map +1 -1
- package/dist/core/types/localization/InsightsFeedCopy.d.ts +5 -0
- package/dist/insights-v2/actionBlocks/TransactionListBlock/layout.d.ts +3 -5
- package/dist/insights-v2/actionBlocks/TransactionListBlock/layout.es.js +41 -36
- package/dist/insights-v2/actionBlocks/TransactionListBlock/layout.es.js.map +1 -1
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js +86 -85
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js.map +1 -1
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.d.ts +4 -0
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.es.js +12 -6
- package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.es.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [9.7.106] - 11-05-2026
|
|
2
|
+
|
|
3
|
+
- **ADDED** - Micro Deposits on Insights 2.0: the deposits as green credits, and a Deposit History drawer (WEC-2109)
|
|
4
|
+
|
|
5
|
+
## [9.7.105] - 11-04-2026
|
|
6
|
+
|
|
7
|
+
- **REMOVED** - Unused dead code from the account filter utilities (MEW-4188)
|
|
8
|
+
|
|
1
9
|
## [9.7.104] - 11-04-2026
|
|
2
10
|
|
|
3
11
|
- **ADDED** - `weekly_small_purchases_block` for the Weekly Small Purchases Summary beat on Insights 2.0 (MEW2-3412): the total and up to 6 merchant logo tiles, the last one a "+N" when there are more
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
import { GlobalStore } from '../../core/stores/GlobalStore';
|
|
2
1
|
import { Account } from '../../core';
|
|
3
|
-
export interface MappedAccounts {
|
|
4
|
-
[key: string]: MappedAccount[];
|
|
5
|
-
}
|
|
6
|
-
export interface MappedAccount {
|
|
7
|
-
accountNumber: string;
|
|
8
|
-
name: string;
|
|
9
|
-
guid: string;
|
|
10
|
-
}
|
|
11
|
-
export interface MappedOptions {
|
|
12
|
-
[key: string]: boolean;
|
|
13
|
-
}
|
|
14
|
-
export declare const setupMappedSelectedOptions: (accounts: Account[], selectedAccountGuids: string[]) => MappedOptions;
|
|
15
|
-
export declare const setupMappedAccounts: (accounts: Account[], closeContentCopy: string, globalStore?: GlobalStore) => MappedAccounts;
|
|
16
2
|
export declare function categorizeAccounts(accounts: Account[]): {
|
|
17
3
|
heldAccounts: Account[];
|
|
18
4
|
externalAccounts: Account[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountFilter.es.js","names":[],"sources":["../../../src/common/utils/AccountFilter.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"AccountFilter.es.js","names":[],"sources":["../../../src/common/utils/AccountFilter.ts"],"sourcesContent":["import type { Account } from '../../core'\nimport { AccountType } from '../../core'\n\nexport function categorizeAccounts(accounts: Account[]): {\n heldAccounts: Account[]\n externalAccounts: Account[]\n} {\n const { heldAccounts, externalAccounts } = accounts.reduce(\n (acc, account) => {\n if (account.member_is_managed_by_user) acc.externalAccounts.push(account)\n else acc.heldAccounts.push(account)\n return acc\n },\n { heldAccounts: [] as Account[], externalAccounts: [] as Account[] },\n )\n\n return {\n heldAccounts: sortByTypePriority(heldAccounts),\n externalAccounts: sortByTypePriority(externalAccounts),\n }\n}\n\nexport function getDisplayAccounts(accounts: Account[], maxAccounts: number): Account[] {\n const { heldAccounts, externalAccounts } = categorizeAccounts(accounts)\n\n const result = heldAccounts.slice(0, maxAccounts)\n\n if (result.length < maxAccounts) {\n result.push(...externalAccounts.slice(0, maxAccounts - result.length))\n }\n\n return result\n}\n\nconst priorityMap: { [key in AccountType]?: number } = {\n [AccountType.CHECKING]: 1,\n [AccountType.SAVINGS]: 2,\n [AccountType.CREDIT_CARD]: 3,\n}\n\nconst getPriority = (accountType: AccountType) => {\n return priorityMap[accountType] ?? accountType + 100\n}\n\nconst sortByTypePriority = (list: Account[]) => {\n return list.sort((a, b) => {\n const aPriority = getPriority(a.account_type)\n const bPriority = getPriority(b.account_type)\n const priorityDiff = aPriority - bPriority\n\n if (priorityDiff !== 0) return priorityDiff\n\n const aName = a.name ?? a.feed_name ?? ''\n const bName = b.name ?? b.feed_name ?? ''\n return aName.localeCompare(bName)\n })\n}\n"],"mappings":";AAGA,SAAgB,EAAmB,GAGjC;AACA,QAAM,EAAE,cAAA,GAAc,kBAAA,EAAA,IAAqB,EAAS,OAAA,CACjD,GAAK,OACA,EAAQ,4BAA2B,EAAI,iBAAiB,KAAK,CAAO,IACnE,EAAI,aAAa,KAAK,CAAO,GAC3B,IAET;AAAA,IAAE,cAAc,CAAC;AAAA,IAAgB,kBAAkB,CAAC;AAAA,EAAe,CACrE;AAEA,SAAO;AAAA,IACL,cAAc,EAAmB,CAAY;AAAA,IAC7C,kBAAkB,EAAmB,CAAgB;AAAA,EACvD;AACF;AAEA,SAAgB,EAAmB,GAAqB,GAAgC;AACtF,QAAM,EAAE,cAAA,GAAc,kBAAA,EAAA,IAAqB,EAAmB,CAAQ,GAEhE,IAAS,EAAa,MAAM,GAAG,CAAW;AAEhD,SAAI,EAAO,SAAS,KAClB,EAAO,KAAK,GAAG,EAAiB,MAAM,GAAG,IAAc,EAAO,MAAM,CAAC,GAGhE;AACT;AAEA,IAAM,IAAiD;AAAA,EACpD,CAAA,EAAY,QAAA,GAAW;AAAA,EACvB,CAAA,EAAY,OAAA,GAAU;AAAA,EACtB,CAAA,EAAY,WAAA,GAAc;AAC7B,GAEM,IAAA,CAAe,MACZ,EAAY,CAAA,KAAgB,IAAc,KAG7C,IAAA,CAAsB,MACnB,EAAK,KAAA,CAAM,GAAG,MAAM;AAGzB,QAAM,IAFY,EAAY,EAAE,YAEX,IADH,EAAY,EAAE,YACC;AAEjC,MAAI,MAAiB,EAAG,QAAO;AAE/B,QAAM,IAAQ,EAAE,QAAQ,EAAE,aAAa,IACjC,IAAQ,EAAE,QAAQ,EAAE,aAAa;AACvC,SAAO,EAAM,cAAc,CAAK;AAClC,CAAC"}
|
|
@@ -133,6 +133,9 @@ export interface TransactionHistoryBlock {
|
|
|
133
133
|
*/
|
|
134
134
|
upcoming_bill_tip_message?: string;
|
|
135
135
|
}
|
|
136
|
+
export interface TransactionListBlockCopy {
|
|
137
|
+
deposit_history_drawer_title?: string;
|
|
138
|
+
}
|
|
136
139
|
export interface HiddenConfirmationCopy {
|
|
137
140
|
title: string;
|
|
138
141
|
description: string;
|
|
@@ -445,6 +448,8 @@ export interface InsightsFeedCopy {
|
|
|
445
448
|
emergency_savings?: EmergencySavingsCopy;
|
|
446
449
|
overflow_menu: OverflowMenuCopy;
|
|
447
450
|
transaction_history_block: TransactionHistoryBlock;
|
|
451
|
+
/** Optional until the localized-content service ships it. */
|
|
452
|
+
transaction_list_block?: TransactionListBlockCopy;
|
|
448
453
|
hidden_confirmation: HiddenConfirmationCopy;
|
|
449
454
|
hide_feedback: HideFeedbackCopy;
|
|
450
455
|
feedback: FeedbackCopy;
|
|
@@ -7,13 +7,11 @@ export declare const TRANSACTION_LIST_VARIANTS: {
|
|
|
7
7
|
readonly GENERIC_LIST: "generic_list";
|
|
8
8
|
/** Opens the list under the beat's title, description and "Learn More". */
|
|
9
9
|
readonly HELP_HEADER: "help_header";
|
|
10
|
+
/** Opens Micro Deposits' Deposit History list. */
|
|
11
|
+
readonly DEPOSIT_HISTORY: "deposit_history";
|
|
10
12
|
};
|
|
11
13
|
export declare const HELP_HEADER_VARIANT: "help_header";
|
|
12
|
-
/**
|
|
13
|
-
* Drawer title: the variant's title when it has one (`generic_list` and `help_header` ->
|
|
14
|
-
* "Transactions"; the help header repeats the beat's title inside the drawer), otherwise the
|
|
15
|
-
* beat's own localized title (`summary_header`, `standard`, or no variant).
|
|
16
|
-
*/
|
|
14
|
+
/** Drawer title: the variant's title when it has one, otherwise the beat's own title. Add new variants here. */
|
|
17
15
|
export declare const getTransactionListDrawerTitle: (variant: string | null | undefined, copy: GlobalCopy, beat?: Beat) => string;
|
|
18
16
|
export interface HelpHeaderContent {
|
|
19
17
|
/** Pre-localized HTML under the title, from the payload's `drilldown_data.description_html`. */
|
|
@@ -1,61 +1,66 @@
|
|
|
1
1
|
import { readHelp as m, toText as o } from "../HelpBlock/layout.es.js";
|
|
2
2
|
import { parseISO as c } from "date-fns/parseISO";
|
|
3
|
-
var
|
|
3
|
+
var n = {
|
|
4
4
|
SUMMARY_HEADER: "summary_header",
|
|
5
5
|
GENERIC_LIST: "generic_list",
|
|
6
|
-
HELP_HEADER: "help_header"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
HELP_HEADER: "help_header",
|
|
7
|
+
DEPOSIT_HISTORY: "deposit_history"
|
|
8
|
+
}, E = n.HELP_HEADER, h = (t, e, r) => {
|
|
9
|
+
switch (t) {
|
|
10
|
+
case n.GENERIC_LIST:
|
|
11
|
+
case n.HELP_HEADER:
|
|
12
|
+
return e.transactions?.transactions_title ?? "";
|
|
13
|
+
case n.DEPOSIT_HISTORY:
|
|
14
|
+
return e.insights_feed?.transaction_list_block?.deposit_history_drawer_title ?? "";
|
|
15
|
+
default:
|
|
16
|
+
return r?.insights_payload?.title ?? "";
|
|
17
|
+
}
|
|
18
|
+
}, A = (t, e) => {
|
|
14
19
|
if (t?.variant !== E) return;
|
|
15
|
-
const
|
|
20
|
+
const r = o(e?.help_label), a = m(e);
|
|
16
21
|
return {
|
|
17
|
-
descriptionHtml: o(
|
|
18
|
-
...
|
|
19
|
-
...
|
|
20
|
-
label:
|
|
22
|
+
descriptionHtml: o(e?.description_html),
|
|
23
|
+
...r && a && { learnMore: {
|
|
24
|
+
...a,
|
|
25
|
+
label: r
|
|
21
26
|
} }
|
|
22
27
|
};
|
|
23
|
-
},
|
|
24
|
-
s.has(t) || (s.add(t), console.warn(
|
|
25
|
-
}, d = (t,
|
|
28
|
+
}, f = (t) => typeof t == "number" && Number.isFinite(t) ? t : void 0, p = (t) => typeof t == "number" && Number.isInteger(t) && t > 0 ? t : void 0, l = Date.UTC(2e3, 0, 1), u = Date.UTC(2100, 0, 1), s = /* @__PURE__ */ new WeakSet(), _ = (t, e) => {
|
|
29
|
+
s.has(t) || (s.add(t), console.warn(e));
|
|
30
|
+
}, d = (t, e, r) => {
|
|
26
31
|
if (t == null || t === "") return;
|
|
27
|
-
let
|
|
28
|
-
if (typeof t == "number" && Number.isFinite(t))
|
|
32
|
+
let a;
|
|
33
|
+
if (typeof t == "number" && Number.isFinite(t)) a = t < 1e12 ? t * 1e3 : t;
|
|
29
34
|
else if (typeof t == "string") {
|
|
30
35
|
const i = c(t).getTime();
|
|
31
|
-
|
|
36
|
+
a = Number.isNaN(i) ? void 0 : i;
|
|
32
37
|
}
|
|
33
|
-
if (
|
|
34
|
-
_(
|
|
38
|
+
if (a === void 0 || a < l || a > u) {
|
|
39
|
+
_(r, `[TransactionListBlock] drilldown_data.${e} is unparseable or out of range (${typeof t})`);
|
|
35
40
|
return;
|
|
36
41
|
}
|
|
37
|
-
return new Date(
|
|
42
|
+
return new Date(a);
|
|
38
43
|
}, D = (t) => {
|
|
39
|
-
if (t?.variant !==
|
|
40
|
-
const
|
|
41
|
-
if (!
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
44
|
-
Object.keys(
|
|
44
|
+
if (t?.variant !== n.SUMMARY_HEADER) return;
|
|
45
|
+
const e = t?.drilldown_data;
|
|
46
|
+
if (!e) return;
|
|
47
|
+
const r = f(e.amount);
|
|
48
|
+
if (r === void 0) {
|
|
49
|
+
Object.keys(e).length > 0 && _(e, "[TransactionListBlock] drilldown_data has no finite `amount` — no summary header.");
|
|
45
50
|
return;
|
|
46
51
|
}
|
|
47
52
|
return {
|
|
48
|
-
amount:
|
|
49
|
-
startDate: d(
|
|
50
|
-
endDate: d(
|
|
51
|
-
count: p(
|
|
53
|
+
amount: r,
|
|
54
|
+
startDate: d(e.start_date, "start_date", e),
|
|
55
|
+
endDate: d(e.end_date, "end_date", e),
|
|
56
|
+
count: p(e.count)
|
|
52
57
|
};
|
|
53
58
|
};
|
|
54
59
|
export {
|
|
55
60
|
E as HELP_HEADER_VARIANT,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
n as TRANSACTION_LIST_VARIANTS,
|
|
62
|
+
h as getTransactionListDrawerTitle,
|
|
63
|
+
A as readHelpHeader,
|
|
59
64
|
D as readSummary
|
|
60
65
|
};
|
|
61
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionListBlock/layout.ts"],"sourcesContent":["import { parseISO } from 'date-fns/parseISO'\n\nimport type {\n Beat,\n DrilldownData,\n GlobalCopy,\n InDescriptionCTA,\n PrimaryCTA,\n SecondaryCTA,\n} from '../../../core'\nimport { readHelp, toText, type HelpContent } from '../HelpBlock/layout'\n\ntype DrilldownCta = PrimaryCTA | SecondaryCTA | InDescriptionCTA\n\n/** The transaction_list_block CTA variants. */\nexport const TRANSACTION_LIST_VARIANTS = {\n SUMMARY_HEADER: 'summary_header',\n GENERIC_LIST: 'generic_list',\n /** Opens the list under the beat's title, description and \"Learn More\". */\n HELP_HEADER: 'help_header',\n
|
|
1
|
+
{"version":3,"file":"layout.es.js","names":[],"sources":["../../../../src/insights-v2/actionBlocks/TransactionListBlock/layout.ts"],"sourcesContent":["import { parseISO } from 'date-fns/parseISO'\n\nimport type {\n Beat,\n DrilldownData,\n GlobalCopy,\n InDescriptionCTA,\n PrimaryCTA,\n SecondaryCTA,\n} from '../../../core'\nimport { readHelp, toText, type HelpContent } from '../HelpBlock/layout'\n\ntype DrilldownCta = PrimaryCTA | SecondaryCTA | InDescriptionCTA\n\n/** The transaction_list_block CTA variants. */\nexport const TRANSACTION_LIST_VARIANTS = {\n SUMMARY_HEADER: 'summary_header',\n GENERIC_LIST: 'generic_list',\n /** Opens the list under the beat's title, description and \"Learn More\". */\n HELP_HEADER: 'help_header',\n /** Opens Micro Deposits' Deposit History list. */\n DEPOSIT_HISTORY: 'deposit_history',\n} as const\n\nexport const HELP_HEADER_VARIANT = TRANSACTION_LIST_VARIANTS.HELP_HEADER\n\n/** Drawer title: the variant's title when it has one, otherwise the beat's own title. Add new variants here. */\nexport const getTransactionListDrawerTitle = (\n variant: string | null | undefined,\n copy: GlobalCopy,\n beat?: Beat,\n): string => {\n switch (variant) {\n case TRANSACTION_LIST_VARIANTS.GENERIC_LIST:\n case TRANSACTION_LIST_VARIANTS.HELP_HEADER:\n return copy.transactions?.transactions_title ?? ''\n case TRANSACTION_LIST_VARIANTS.DEPOSIT_HISTORY:\n return copy.insights_feed?.transaction_list_block?.deposit_history_drawer_title ?? ''\n default:\n return beat?.insights_payload?.title ?? ''\n }\n}\n\nexport interface HelpHeaderContent {\n /** Pre-localized HTML under the title, from the payload's `drilldown_data.description_html`. */\n descriptionHtml?: string\n /** The \"Learn More\" link and the help drawer it opens; absent when the beat carries no help. */\n learnMore?: HelpContent & { label: string }\n}\n\n/**\n * The help-header variant's text, read from the payload's `drilldown_data` (shared by every CTA\n * of the card): `description_html`, and `help_label` with the `help_title` / `help_html` that\n * `readHelp` reads. Only the `help_header` variant renders the block.\n */\nexport const readHelpHeader = (\n cta: DrilldownCta | undefined,\n drilldown: DrilldownData | undefined,\n): HelpHeaderContent | undefined => {\n if (cta?.variant !== HELP_HEADER_VARIANT) return undefined\n\n const label = toText(drilldown?.help_label)\n const help = readHelp(drilldown)\n\n return {\n descriptionHtml: toText(drilldown?.description_html),\n ...(label && help && { learnMore: { ...help, label } }),\n }\n}\n\nexport interface TransactionListSummary {\n /** Headline figure (e.g. total withdrawn). */\n amount: number\n /** Validated range endpoints; rendered as `{start} – {end}`. Omitted when the payload value is\n * missing or unparseable (so the drawer never crashes on an Invalid Date). */\n startDate?: Date\n endDate?: Date\n /** Number of transactions for the pill, from the CTA's `drilldown_data.count`. */\n count?: number\n}\n\nconst toFiniteNumber = (value: unknown): number | undefined =>\n typeof value === 'number' && Number.isFinite(value) ? value : undefined\n\n// `> 0`: the card only shows with >= 1 guid, so a `count` of 0 is dropped and falls back to the\n// guid count rather than rendering \"0 transactions\".\nconst toCount = (value: unknown): number | undefined =>\n typeof value === 'number' && Number.isInteger(value) && value > 0 ? value : undefined\n\n// Sane epoch window so a bad/typo payload can't render a far-past/future date.\nconst EPOCH_MIN = Date.UTC(2000, 0, 1)\nconst EPOCH_MAX = Date.UTC(2100, 0, 1)\n\n// `readSummary` runs on every observer re-render (no `useMemo` by design), so warn at most once per\n// distinct payload object instead of on every render. Keyed on the `drilldown_data` object, which is\n// a stable reference across re-renders of the same beat.\nconst warnedPayloads = new WeakSet<object>()\nconst warnOncePerPayload = (source: object, message: string): void => {\n if (warnedPayloads.has(source)) return\n warnedPayloads.add(source)\n console.warn(message)\n}\n\n/**\n * Parse a payload date value to a validated `Date`, or `undefined`. Accepts unix seconds or\n * milliseconds (auto-detected) and ISO strings. Fails closed (no throw): an unparseable or\n * out-of-range value returns undefined and warns, so `formatDate`/`intlFormat` never sees an Invalid\n * Date (which throws `RangeError` and takes down the whole drawer render).\n */\nconst toDate = (value: unknown, field: string, source: object): Date | undefined => {\n // Missing/empty is a normal \"no range\" case — return quietly, don't warn.\n if (value === undefined || value === null || value === '') return undefined\n\n let ms: number | undefined\n if (typeof value === 'number' && Number.isFinite(value)) {\n // < 1e12 is treated as seconds (1e12 ms is year 33658). Trade-off: genuine ms timestamps from\n // ~2000-2001 would be misread as seconds and fall outside the window below (dropped, not shown).\n ms = value < 1e12 ? value * 1000 : value\n } else if (typeof value === 'string') {\n const parsed = parseISO(value).getTime()\n ms = Number.isNaN(parsed) ? undefined : parsed\n }\n\n if (ms === undefined || ms < EPOCH_MIN || ms > EPOCH_MAX) {\n warnOncePerPayload(\n source,\n `[TransactionListBlock] drilldown_data.${field} is unparseable or out of range (${typeof value})`,\n )\n return undefined\n }\n return new Date(ms)\n}\n\n/**\n * Summary-header figures for the drawer, read from the clicked CTA's `drilldown_data` (the backend\n * hangs a drilldown's own data off the CTA that opens it). Fails closed throughout: only the\n * `summary_header` variant renders a header (so figures from a different CTA that `getDynamicCta…`\n * fell back to can't be misattributed), then without a finite `amount` there is still no header, and\n * each date is validated to a real `Date` or dropped — an unparseable value never reaches\n * `formatDate` (which throws on an Invalid Date).\n *\n * `drilldown_data` fields: `amount` (number), `start_date`/`end_date` (unix seconds|ms or ISO),\n * `count` (number of transactions).\n */\nexport const readSummary = (cta: DrilldownCta | undefined): TransactionListSummary | undefined => {\n // Defense-in-depth on financial figures: only the summary-header variant shows the card.\n if (cta?.variant !== TRANSACTION_LIST_VARIANTS.SUMMARY_HEADER) return undefined\n\n const source = cta?.drilldown_data\n if (!source) return undefined\n\n const amount = toFiniteNumber(source.amount)\n if (amount === undefined) {\n // `drilldown_data` present but no usable amount -> surface the likely contract drift (field\n // rename) instead of a silently missing header.\n if (Object.keys(source).length > 0) {\n warnOncePerPayload(\n source,\n '[TransactionListBlock] drilldown_data has no finite `amount` — no summary header.',\n )\n }\n return undefined\n }\n\n return {\n amount,\n startDate: toDate(source.start_date, 'start_date', source),\n endDate: toDate(source.end_date, 'end_date', source),\n count: toCount(source.count),\n }\n}\n"],"mappings":";;AAeA,IAAa,IAA4B;AAAA,EACvC,gBAAgB;AAAA,EAChB,cAAc;AAAA,EAEd,aAAa;AAAA,EAEb,iBAAiB;AACnB,GAEa,IAAsB,EAA0B,aAGhD,IAAA,CACX,GACA,GACA,MACW;AACX,UAAQ,GAAR;AAAA,IACE,KAAK,EAA0B;AAAA,IAC/B,KAAK,EAA0B;AAC7B,aAAO,EAAK,cAAc,sBAAsB;AAAA,IAClD,KAAK,EAA0B;AAC7B,aAAO,EAAK,eAAe,wBAAwB,gCAAgC;AAAA,IACrF;AACE,aAAO,GAAM,kBAAkB,SAAS;AAAA,EAC5C;AACF,GAca,IAAA,CACX,GACA,MACkC;AAClC,MAAI,GAAK,YAAY,EAAqB;AAE1C,QAAM,IAAQ,EAAO,GAAW,UAAU,GACpC,IAAO,EAAS,CAAS;AAE/B,SAAO;AAAA,IACL,iBAAiB,EAAO,GAAW,gBAAgB;AAAA,IACnD,GAAI,KAAS,KAAQ,EAAE,WAAW;AAAA,MAAE,GAAG;AAAA,MAAM,OAAA;AAAA,IAAM,EAAE;AAAA,EACvD;AACF,GAaM,IAAA,CAAkB,MACtB,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,IAAI,IAAQ,QAI1D,IAAA,CAAW,MACf,OAAO,KAAU,YAAY,OAAO,UAAU,CAAK,KAAK,IAAQ,IAAI,IAAQ,QAGxE,IAAY,KAAK,IAAI,KAAM,GAAG,CAAC,GAC/B,IAAY,KAAK,IAAI,MAAM,GAAG,CAAC,GAK/B,IAAiB,oBAAI,QAAgB,GACrC,IAAA,CAAsB,GAAgB,MAA0B;AACpE,EAAI,EAAe,IAAI,CAAM,MAC7B,EAAe,IAAI,CAAM,GACzB,QAAQ,KAAK,CAAO;AACtB,GAQM,IAAA,CAAU,GAAgB,GAAe,MAAqC;AAElF,MAA2B,KAAU,QAAQ,MAAU,GAAI;AAE3D,MAAI;AACJ,MAAI,OAAO,KAAU,YAAY,OAAO,SAAS,CAAK,EAGpD,CAAA,IAAK,IAAQ,OAAO,IAAQ,MAAO;AAAA,WAC1B,OAAO,KAAU,UAAU;AACpC,UAAM,IAAS,EAAS,CAAK,EAAE,QAAQ;AACvC,IAAA,IAAK,OAAO,MAAM,CAAM,IAAI,SAAY;AAAA,EAC1C;AAEA,MAAI,MAAO,UAAa,IAAK,KAAa,IAAK,GAAW;AACxD,IAAA,EACE,GACA,yCAAyC,CAAA,oCAAyC,OAAO,CAAA,GAC3F;AACA;AAAA,EACF;AACA,SAAO,IAAI,KAAK,CAAE;AACpB,GAaa,IAAA,CAAe,MAAsE;AAEhG,MAAI,GAAK,YAAY,EAA0B,eAAgB;AAE/D,QAAM,IAAS,GAAK;AACpB,MAAI,CAAC,EAAQ;AAEb,QAAM,IAAS,EAAe,EAAO,MAAM;AAC3C,MAAI,MAAW,QAAW;AAGxB,IAAI,OAAO,KAAK,CAAM,EAAE,SAAS,KAC/B,EACE,GACA,mFACF;AAEF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAA;AAAA,IACA,WAAW,EAAO,EAAO,YAAY,cAAc,CAAM;AAAA,IACzD,SAAS,EAAO,EAAO,UAAU,YAAY,CAAM;AAAA,IACnD,OAAO,EAAQ,EAAO,KAAK;AAAA,EAC7B;AACF"}
|
|
@@ -1,147 +1,148 @@
|
|
|
1
|
-
import { useCategoryStore as
|
|
1
|
+
import { useCategoryStore as H, useGlobalCopyStore as P, useGlobalStore as V } from "../../../../common/context/hooks.es.js";
|
|
2
2
|
import { slot as s } from "../../../../core/types/Insights.es.js";
|
|
3
|
-
import { formatCurrency as
|
|
4
|
-
import { getCategoryColor as
|
|
5
|
-
import { useBeatActions as
|
|
6
|
-
import { USER_RESPONSE as
|
|
7
|
-
import { logoFromRef as
|
|
8
|
-
import
|
|
9
|
-
import { statusIconName as
|
|
10
|
-
import { resolveVariantConfig as
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import { subscriptionFrequency as
|
|
14
|
-
import { getLayoutConfig as
|
|
15
|
-
import { observer as
|
|
16
|
-
import { CategoryIcon as
|
|
17
|
-
import { Icon as
|
|
18
|
-
import { jsx as
|
|
19
|
-
import { alpha as
|
|
3
|
+
import { formatCurrency as C } from "../../../../core/utils/NumberFormatting.es.js";
|
|
4
|
+
import { getCategoryColor as I } from "../../../../core/utils/CategoryUtil.es.js";
|
|
5
|
+
import { useBeatActions as U } from "../../../beatActions.es.js";
|
|
6
|
+
import { USER_RESPONSE as W, repeatingTransactionOf as Y } from "../../../ctaActions/subscriptionAnswer.es.js";
|
|
7
|
+
import { logoFromRef as J } from "../../../components/shared/EntityLogo.es.js";
|
|
8
|
+
import K from "../../../components/LogoFromGuid.es.js";
|
|
9
|
+
import { statusIconName as Q, statusIconPalette as S } from "../../../components/statusIcon.es.js";
|
|
10
|
+
import { resolveVariantConfig as X } from "../../resolveVariantConfig.es.js";
|
|
11
|
+
import oo from "../../../components/TransactionListCard.es.js";
|
|
12
|
+
import to from "../../../components/StatusMessageCard.es.js";
|
|
13
|
+
import { subscriptionFrequency as ro } from "../../../components/SubscriptionStatus/subscriptionFrequency.es.js";
|
|
14
|
+
import { getLayoutConfig as eo, transactionBlockVariant as io } from "./layout.es.js";
|
|
15
|
+
import { observer as no } from "mobx-react-lite";
|
|
16
|
+
import { CategoryIcon as ao, InstitutionLogo as so, MerchantLogo as co } from "@mxenabled/mxui";
|
|
17
|
+
import { Icon as E } from "@mxenabled/mx-icons";
|
|
18
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
19
|
+
import { alpha as G, useTheme as uo } from "@mui/material/styles";
|
|
20
20
|
import d from "@mui/material/Box";
|
|
21
|
-
var u = 32,
|
|
22
|
-
const
|
|
23
|
-
return
|
|
21
|
+
var u = 32, mo = Math.round(u * 0.625), lo = 24, T = 32, go = 20, fo = ({ icon: a }) => {
|
|
22
|
+
const n = Q(a?.guid);
|
|
23
|
+
return n ? /* @__PURE__ */ r(d, {
|
|
24
24
|
"aria-hidden": !0,
|
|
25
|
-
"data-icon":
|
|
25
|
+
"data-icon": n,
|
|
26
26
|
"data-testid": "subscription-badge",
|
|
27
27
|
sx: {
|
|
28
28
|
alignItems: "center",
|
|
29
|
-
bgcolor: `${
|
|
29
|
+
bgcolor: `${S(a?.color)}.main`,
|
|
30
30
|
borderRadius: "50%",
|
|
31
31
|
display: "flex",
|
|
32
|
-
height:
|
|
32
|
+
height: T,
|
|
33
33
|
justifyContent: "center",
|
|
34
|
-
width:
|
|
34
|
+
width: T
|
|
35
35
|
},
|
|
36
|
-
children: /* @__PURE__ */
|
|
36
|
+
children: /* @__PURE__ */ r(E, {
|
|
37
37
|
fill: !0,
|
|
38
|
-
name:
|
|
39
|
-
size:
|
|
40
|
-
sx: { color: `${
|
|
38
|
+
name: n,
|
|
39
|
+
size: go,
|
|
40
|
+
sx: { color: `${S(a?.color)}.contrastText` }
|
|
41
41
|
})
|
|
42
42
|
}) : null;
|
|
43
|
-
},
|
|
44
|
-
const o =
|
|
43
|
+
}, po = (a, n, c, m) => {
|
|
44
|
+
const o = J(a.logo, a.primary_text);
|
|
45
45
|
if (o) {
|
|
46
46
|
if (o.logo_name) {
|
|
47
|
-
const
|
|
48
|
-
return /* @__PURE__ */
|
|
47
|
+
const i = !!o.logo_fill, e = o.logo_color ?? c.palette.chart.chart2 ?? c.palette.primary.main;
|
|
48
|
+
return /* @__PURE__ */ r(d, {
|
|
49
49
|
sx: {
|
|
50
50
|
alignItems: "center",
|
|
51
51
|
display: "flex",
|
|
52
52
|
height: u,
|
|
53
53
|
justifyContent: "center",
|
|
54
54
|
width: u,
|
|
55
|
-
...
|
|
56
|
-
bgcolor:
|
|
55
|
+
...i && {
|
|
56
|
+
bgcolor: G(e, 0.15),
|
|
57
57
|
borderRadius: "8px"
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
|
-
children: /* @__PURE__ */
|
|
60
|
+
children: /* @__PURE__ */ r(E, {
|
|
61
61
|
name: o.logo_name,
|
|
62
|
-
size:
|
|
63
|
-
sx: { color:
|
|
62
|
+
size: mo,
|
|
63
|
+
sx: { color: i ? e : o.logo_color }
|
|
64
64
|
})
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
|
-
if (o.merchant_guid) return /* @__PURE__ */
|
|
67
|
+
if (o.merchant_guid) return /* @__PURE__ */ r(co, {
|
|
68
68
|
alt: o.merchant_name ?? "",
|
|
69
|
-
categoryGuid: o.category_guid ?
|
|
69
|
+
categoryGuid: o.category_guid ? n(o.category_guid) : "",
|
|
70
70
|
merchantGuid: o.merchant_guid,
|
|
71
71
|
size: u
|
|
72
72
|
});
|
|
73
|
-
if (o.institution_guid) return /* @__PURE__ */
|
|
73
|
+
if (o.institution_guid) return /* @__PURE__ */ r(so, {
|
|
74
74
|
alt: o.institution_name ?? "",
|
|
75
75
|
institutionGuid: o.institution_guid,
|
|
76
76
|
size: u
|
|
77
77
|
});
|
|
78
78
|
if (o.category_guid) {
|
|
79
|
-
const
|
|
80
|
-
bgcolor:
|
|
81
|
-
border: `1px solid ${
|
|
79
|
+
const i = n(o.category_guid), e = m ? {
|
|
80
|
+
bgcolor: G(I(i, c), 0.15),
|
|
81
|
+
border: `1px solid ${I(i, c)}`,
|
|
82
82
|
color: "text.primary"
|
|
83
83
|
} : void 0;
|
|
84
|
-
return /* @__PURE__ */
|
|
85
|
-
"data-testid": `category-icon-${
|
|
84
|
+
return /* @__PURE__ */ r(d, {
|
|
85
|
+
"data-testid": `category-icon-${i}`,
|
|
86
86
|
sx: { display: "flex" },
|
|
87
|
-
children: /* @__PURE__ */
|
|
88
|
-
categoryGuid:
|
|
87
|
+
children: /* @__PURE__ */ r(ao, {
|
|
88
|
+
categoryGuid: i,
|
|
89
89
|
size: u,
|
|
90
|
-
sx:
|
|
90
|
+
sx: e
|
|
91
91
|
})
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
},
|
|
96
|
-
const
|
|
97
|
-
beat:
|
|
98
|
-
stores:
|
|
99
|
-
}) : void 0, h = !!g && _?.user_response ===
|
|
100
|
-
if (
|
|
101
|
-
const
|
|
102
|
-
return typeof
|
|
103
|
-
icon: /* @__PURE__ */
|
|
95
|
+
}, Fo = no(({ payload: a }) => {
|
|
96
|
+
const n = uo(), { getTopLevelCategoryGuid: c } = H(), m = V(), { recurring: o } = P(), { beat: i } = U(), { data: e, variant: B } = a.instance_slot, { answeredBackground: p, background: l, cardVariant: L, creditAmounts: k, elevated: O, followsSubscription: g, headerColor: R, raised: A, showFooter: $, showFrequency: y, showHeader: z, statusMessage: F, sx: N, tintedCategoryLogo: M } = X(eo(n), B, io.NoHeader, "TransactionBlock"), _ = (y || g) && i ? Y({
|
|
97
|
+
beat: i,
|
|
98
|
+
stores: m
|
|
99
|
+
}) : void 0, h = !!g && _?.user_response === W.CONFIRMED;
|
|
100
|
+
if (F) {
|
|
101
|
+
const t = s(e, "message");
|
|
102
|
+
return typeof t != "string" || !t.trim() ? (console.warn("[TransactionBlock] status_message has no message — rendering nothing."), null) : /* @__PURE__ */ r(to, {
|
|
103
|
+
icon: /* @__PURE__ */ r(d, {
|
|
104
104
|
"aria-hidden": "true",
|
|
105
105
|
sx: { display: "flex" },
|
|
106
|
-
children: /* @__PURE__ */
|
|
107
|
-
logo: s(
|
|
108
|
-
size:
|
|
106
|
+
children: /* @__PURE__ */ r(K, {
|
|
107
|
+
logo: s(e, "icon"),
|
|
108
|
+
size: lo
|
|
109
109
|
})
|
|
110
110
|
}),
|
|
111
|
-
message:
|
|
112
|
-
sx:
|
|
113
|
-
backgroundImage:
|
|
111
|
+
message: t,
|
|
112
|
+
sx: l ? {
|
|
113
|
+
backgroundImage: l,
|
|
114
114
|
bgcolor: "background.paper"
|
|
115
115
|
} : void 0
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
|
-
const f = s(
|
|
118
|
+
const f = s(e, "series"), x = s(e, "header_text");
|
|
119
119
|
if (!Array.isArray(f) || !f.length) return null;
|
|
120
|
-
const
|
|
120
|
+
const Z = z && typeof x == "string" ? x : void 0, b = s(e, "footer_text"), w = s(e, "footer_amount"), j = $ && typeof b == "string" ? {
|
|
121
121
|
label: b,
|
|
122
|
-
amount:
|
|
123
|
-
} : void 0,
|
|
124
|
-
return /* @__PURE__ */
|
|
125
|
-
background: h && p ? p :
|
|
126
|
-
badge:
|
|
127
|
-
elevated:
|
|
128
|
-
footer:
|
|
129
|
-
header:
|
|
130
|
-
headerColor:
|
|
131
|
-
raised:
|
|
132
|
-
sx:
|
|
133
|
-
variant:
|
|
134
|
-
rows: f.map((
|
|
135
|
-
amount: typeof
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
amount: C(w, "0,0.00")
|
|
123
|
+
} : void 0, q = y ? ro(o, _) : void 0, D = g ? /* @__PURE__ */ r(fo, { icon: s(e, h ? "reviewed_icon" : "icon") }) : void 0, v = (t) => !!k && typeof t == "number" && t > 0;
|
|
124
|
+
return /* @__PURE__ */ r(oo, {
|
|
125
|
+
background: h && p ? p : l,
|
|
126
|
+
badge: D,
|
|
127
|
+
elevated: O,
|
|
128
|
+
footer: j,
|
|
129
|
+
header: Z,
|
|
130
|
+
headerColor: R,
|
|
131
|
+
raised: A,
|
|
132
|
+
sx: N,
|
|
133
|
+
variant: L,
|
|
134
|
+
rows: f.map((t) => ({
|
|
135
|
+
amount: typeof t.amount == "number" ? `${v(t.amount) ? "+" : ""}${C(t.amount, "0,0.00")}` : "",
|
|
136
|
+
amountColor: v(t.amount) ? "success.main" : void 0,
|
|
137
|
+
amountCaption: q,
|
|
138
|
+
leading: po(t, c, n, M ?? !1),
|
|
139
|
+
subtitle: t.secondary_text ?? "",
|
|
140
|
+
title: t.primary_text ?? ""
|
|
140
141
|
}))
|
|
141
142
|
});
|
|
142
143
|
});
|
|
143
144
|
export {
|
|
144
|
-
|
|
145
|
+
Fo as TransactionBlock
|
|
145
146
|
};
|
|
146
147
|
|
|
147
148
|
//# sourceMappingURL=TransactionBlock.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport Box from '@mui/material/Box'\nimport { alpha, useTheme } from '@mui/material/styles'\nimport type { Theme } from '@mui/material/styles'\n\nimport { CategoryIcon, InstitutionLogo, MerchantLogo } from '@mxenabled/mxui'\nimport { Icon } from '@mxenabled/mx-icons'\n\nimport { useCategoryStore, useGlobalCopyStore, useGlobalStore } from '../../../../common'\nimport { slot } from '../../../../core'\nimport type { InsightsPayload, InstanceSlotRow, LogoRef } from '../../../../core'\nimport { getCategoryColor } from '../../../../core/utils/CategoryUtil'\nimport { formatCurrency } from '../../../../core/utils/NumberFormatting'\n\nimport { useBeatActions } from '../../../beatActions'\nimport LogoFromGuid from '../../../components/LogoFromGuid'\nimport StatusMessageCard from '../../../components/StatusMessageCard'\nimport TransactionListCard from '../../../components/TransactionListCard'\nimport { logoFromRef } from '../../../components/shared/EntityLogo'\nimport { statusIconName, statusIconPalette } from '../../../components/statusIcon'\nimport { subscriptionFrequency } from '../../../components/SubscriptionStatus/subscriptionFrequency'\nimport { repeatingTransactionOf, USER_RESPONSE } from '../../../ctaActions/subscriptionAnswer'\n\nimport { resolveVariantConfig } from '../../resolveVariantConfig'\nimport { getLayoutConfig, transactionBlockVariant } from './layout'\n\ninterface TransactionBlockProps {\n payload: InsightsPayload\n beatGuid?: string\n}\n\nconst ROW_LOGO_SIZE = 32\n// Same glyph-to-tile ratio mxui's `CategoryIcon` uses, so a status icon sits like the other logos.\nconst ROW_ICON_SIZE = Math.round(ROW_LOGO_SIZE * 0.625)\nconst STATUS_ICON_SIZE = 24\n// Status badge: palette disc, contrastText glyph.\nconst BADGE_SIZE = 32\nconst BADGE_GLYPH_SIZE = 20\n\n/** Status disc from `data.icon` / `data.reviewed_icon`. */\nconst SubscriptionBadge = ({ icon }: { icon?: LogoRef }) => {\n const name = statusIconName(icon?.guid)\n\n if (!name) return null\n\n return (\n <Box\n aria-hidden={true}\n data-icon={name}\n data-testid=\"subscription-badge\"\n sx={{\n alignItems: 'center',\n bgcolor: `${statusIconPalette(icon?.color)}.main`,\n borderRadius: '50%',\n display: 'flex',\n height: BADGE_SIZE,\n justifyContent: 'center',\n width: BADGE_SIZE,\n }}\n >\n <Icon\n fill={true}\n name={name}\n size={BADGE_GLYPH_SIZE}\n sx={{ color: `${statusIconPalette(icon?.color)}.contrastText` }}\n />\n </Box>\n )\n}\n\n/**\n * Renders the row's leading logo from its `LogoRef`: a status icon, or an entity guid whose prefix\n * names the entity. An unrecognized prefix renders no logo rather than guessing.\n *\n * `resolveTopLevelCategory`: mxui's `CategoryIcon` only knows the top-level category guids and\n * silently falls back to the Uncategorized icon for a sub-category. The details drawer avoids\n * this by passing `transaction.top_level_category_guid`; the row only has the raw guid, so it is\n * walked up to its parent here (identity until categories load). That resolution applies both to a\n * `CAT-` row logo and to a merchant's `fallback_guid`. The tinted/bordered tile is opt-in per variant\n * (`tintedCategoryLogo`) and only styles the `CAT-` row branch; a merchant's `fallback_guid` is drawn\n * by `MerchantLogo`'s own untinted `CategoryIcon` fallback when the merchant image fails to load.\n */\nconst renderRowLogo = (\n row: InstanceSlotRow,\n resolveTopLevelCategory: (guid: string) => string,\n theme: Theme,\n tintedCategoryLogo: boolean,\n) => {\n const logo = logoFromRef(row.logo, row.primary_text)\n\n if (!logo) return undefined\n\n if (logo.logo_name) {\n // A `{ icon, color }` status logo (e.g. an overdraft warning) renders as a bare coloured glyph.\n // An ICO- fill logo (the Weekly New Merchants \"Others\" row - `logo_fill` is set for ICO- refs\n // only, in EntityLogo) renders as an accent tile: per the MX accent-icon pattern the background is\n // the tile colour at 15% opacity and the glyph is the full tile colour (Figma). The tile colour is\n // the logo's own colour when it carries one, else chart-2 - so tile and glyph always match.\n const accentTile = !!logo.logo_fill\n const tileColor = logo.logo_color ?? theme.palette.chart.chart2 ?? theme.palette.primary.main\n return (\n <Box\n sx={{\n alignItems: 'center',\n display: 'flex',\n height: ROW_LOGO_SIZE,\n justifyContent: 'center',\n width: ROW_LOGO_SIZE,\n ...(accentTile && {\n bgcolor: alpha(tileColor, 0.15),\n borderRadius: '8px',\n }),\n }}\n >\n <Icon\n name={logo.logo_name}\n size={ROW_ICON_SIZE}\n sx={{ color: accentTile ? tileColor : logo.logo_color }}\n />\n </Box>\n )\n }\n\n if (logo.merchant_guid) {\n return (\n <MerchantLogo\n alt={logo.merchant_name ?? ''}\n categoryGuid={logo.category_guid ? resolveTopLevelCategory(logo.category_guid) : ''}\n merchantGuid={logo.merchant_guid}\n size={ROW_LOGO_SIZE}\n />\n )\n }\n\n if (logo.institution_guid) {\n return (\n <InstitutionLogo\n alt={logo.institution_name ?? ''}\n institutionGuid={logo.institution_guid}\n size={ROW_LOGO_SIZE}\n />\n )\n }\n\n if (logo.category_guid) {\n const topLevelGuid = resolveTopLevelCategory(logo.category_guid)\n // When the variant opts in (`tintedCategoryLogo`), the tile is the Budget-style accent: the\n // category colour at 15% opacity, a 1px category-colour border, and a `text.primary` glyph\n // (Figma - Replenish Savings' multi-account Transfer row). Otherwise mxui's default tile, so other\n // beats' category logos are unchanged.\n const tintSx = tintedCategoryLogo\n ? {\n bgcolor: alpha(getCategoryColor(topLevelGuid, theme), 0.15),\n border: `1px solid ${getCategoryColor(topLevelGuid, theme)}`,\n color: 'text.primary',\n }\n : undefined\n return (\n <Box data-testid={`category-icon-${topLevelGuid}`} sx={{ display: 'flex' }}>\n <CategoryIcon categoryGuid={topLevelGuid} size={ROW_LOGO_SIZE} sx={tintSx} />\n </Box>\n )\n }\n\n return undefined\n}\n\n/**\n * The `transaction_block`: rows the backend already localized, carried inline on\n * `instance_slot.data.series` (`logo`, `primary_text`, `secondary_text`, `amount`). Only the\n * amount is formatted here, because the contract sends it as a number. `instance_slot.variant`\n * picks the header and slot treatment from `./layout.ts`.\n *\n * This is the full/mini shape. The reduced widgets (micro, embedded) resolve to the row logo\n * alone, carried flat on `data.logo` with no `series`, and are drawn by `CompactInsightCard`.\n *\n * `status_message` draws no rows: `data.message` beside the `data.icon` logo, as a\n * `StatusMessageCard` banner (Uncategorized Transactions V2 `complete`).\n *\n * A header, when the variant shows one, comes from `instance_slot.data.header_text` (the\n * transaction date, or \"{count} transactions\"). It deliberately does *not* come from the first\n * row: on a `with_merchant` card a row's `secondary_text` is the category, so reading it here\n * rendered the category twice and dropped the date entirely.\n *\n * A footer/summary row (Replenish Savings' \"Remaining Balance\", Weekly New Merchants' \"Total\")\n * renders when the variant's `showFooter` config is set (`with_header_footer`, `with_footer`), from\n * `data.footer_text` with `data.footer_amount` beside it, formatted like the row amounts (the\n * contract sends it as a number).\n */\nexport const TransactionBlock = observer(({ payload }: TransactionBlockProps) => {\n const theme = useTheme()\n const { getTopLevelCategoryGuid } = useCategoryStore()\n const stores = useGlobalStore()\n const { recurring: recurringCopy } = useGlobalCopyStore()\n const { beat } = useBeatActions()\n const { data, variant } = payload.instance_slot\n // The plain row is the safe default: it adds nothing a wrong variant could misstate.\n const {\n answeredBackground,\n background,\n cardVariant,\n elevated,\n followsSubscription,\n headerColor,\n raised,\n showFooter,\n showFrequency,\n showHeader,\n statusMessage,\n sx,\n tintedCategoryLogo,\n } = resolveVariantConfig(\n getLayoutConfig(theme),\n variant,\n transactionBlockVariant.NoHeader,\n 'TransactionBlock',\n )\n\n // The live repeating transaction (read-only), for the frequency and the badge / answered wash.\n const repeating =\n (showFrequency || followsSubscription) && beat\n ? repeatingTransactionOf({ beat, stores })\n : undefined\n const subscribed = !!followsSubscription && repeating?.user_response === USER_RESPONSE.CONFIRMED\n\n if (statusMessage) {\n const message = slot<string>(data, 'message')\n if (typeof message !== 'string' || !message.trim()) {\n console.warn('[TransactionBlock] status_message has no message — rendering nothing.')\n return null\n }\n\n // The icon only decorates the message, so it is hidden from the status announcement.\n return (\n <StatusMessageCard\n icon={\n <Box aria-hidden=\"true\" sx={{ display: 'flex' }}>\n <LogoFromGuid logo={slot<LogoRef>(data, 'icon')} size={STATUS_ICON_SIZE} />\n </Box>\n }\n message={message}\n // The 20% wash layers over paper, as Figma's slot does.\n sx={background ? { backgroundImage: background, bgcolor: 'background.paper' } : undefined}\n />\n )\n }\n\n const series = slot<InstanceSlotRow[]>(data, 'series')\n const headerText = slot<string>(data, 'header_text')\n\n if (!Array.isArray(series) || !series.length) return null\n\n const header = showHeader && typeof headerText === 'string' ? headerText : undefined\n\n const footerText = slot<string>(data, 'footer_text')\n const footerAmount = slot<number>(data, 'footer_amount')\n const footer =\n showFooter && typeof footerText === 'string'\n ? {\n label: footerText,\n amount: formatCurrency(footerAmount, '0,0.00'),\n }\n : undefined\n\n // Live, as pulse: the repeating transaction the CTA's `prepare` loads.\n const frequency = showFrequency ? subscriptionFrequency(recurringCopy, repeating) : undefined\n const badge = followsSubscription ? (\n <SubscriptionBadge icon={slot<LogoRef>(data, subscribed ? 'reviewed_icon' : 'icon')} />\n ) : undefined\n\n return (\n <TransactionListCard\n background={subscribed && answeredBackground ? answeredBackground : background}\n badge={badge}\n elevated={elevated}\n footer={footer}\n header={header}\n headerColor={headerColor}\n raised={raised}\n sx={sx}\n variant={cardVariant}\n rows={series.map((row) => ({\n amount: typeof row.amount === 'number' ? formatCurrency(row.amount, '0,0.00') : '',\n amountCaption: frequency,\n leading: renderRowLogo(row, getTopLevelCategoryGuid, theme, tintedCategoryLogo ?? false),\n subtitle: row.secondary_text ?? '',\n title: row.primary_text ?? '',\n }))}\n />\n )\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TransactionBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport Box from '@mui/material/Box'\nimport { alpha, useTheme } from '@mui/material/styles'\nimport type { Theme } from '@mui/material/styles'\n\nimport { CategoryIcon, InstitutionLogo, MerchantLogo } from '@mxenabled/mxui'\nimport { Icon } from '@mxenabled/mx-icons'\n\nimport { useCategoryStore, useGlobalCopyStore, useGlobalStore } from '../../../../common'\nimport { slot } from '../../../../core'\nimport type { InsightsPayload, InstanceSlotRow, LogoRef } from '../../../../core'\nimport { getCategoryColor } from '../../../../core/utils/CategoryUtil'\nimport { formatCurrency } from '../../../../core/utils/NumberFormatting'\n\nimport { useBeatActions } from '../../../beatActions'\nimport LogoFromGuid from '../../../components/LogoFromGuid'\nimport StatusMessageCard from '../../../components/StatusMessageCard'\nimport TransactionListCard from '../../../components/TransactionListCard'\nimport { logoFromRef } from '../../../components/shared/EntityLogo'\nimport { statusIconName, statusIconPalette } from '../../../components/statusIcon'\nimport { subscriptionFrequency } from '../../../components/SubscriptionStatus/subscriptionFrequency'\nimport { repeatingTransactionOf, USER_RESPONSE } from '../../../ctaActions/subscriptionAnswer'\n\nimport { resolveVariantConfig } from '../../resolveVariantConfig'\nimport { getLayoutConfig, transactionBlockVariant } from './layout'\n\ninterface TransactionBlockProps {\n payload: InsightsPayload\n beatGuid?: string\n}\n\nconst ROW_LOGO_SIZE = 32\n// Same glyph-to-tile ratio mxui's `CategoryIcon` uses, so a status icon sits like the other logos.\nconst ROW_ICON_SIZE = Math.round(ROW_LOGO_SIZE * 0.625)\nconst STATUS_ICON_SIZE = 24\n// Status badge: palette disc, contrastText glyph.\nconst BADGE_SIZE = 32\nconst BADGE_GLYPH_SIZE = 20\n\n/** Status disc from `data.icon` / `data.reviewed_icon`. */\nconst SubscriptionBadge = ({ icon }: { icon?: LogoRef }) => {\n const name = statusIconName(icon?.guid)\n\n if (!name) return null\n\n return (\n <Box\n aria-hidden={true}\n data-icon={name}\n data-testid=\"subscription-badge\"\n sx={{\n alignItems: 'center',\n bgcolor: `${statusIconPalette(icon?.color)}.main`,\n borderRadius: '50%',\n display: 'flex',\n height: BADGE_SIZE,\n justifyContent: 'center',\n width: BADGE_SIZE,\n }}\n >\n <Icon\n fill={true}\n name={name}\n size={BADGE_GLYPH_SIZE}\n sx={{ color: `${statusIconPalette(icon?.color)}.contrastText` }}\n />\n </Box>\n )\n}\n\n/**\n * Renders the row's leading logo from its `LogoRef`: a status icon, or an entity guid whose prefix\n * names the entity. An unrecognized prefix renders no logo rather than guessing.\n *\n * `resolveTopLevelCategory`: mxui's `CategoryIcon` only knows the top-level category guids and\n * silently falls back to the Uncategorized icon for a sub-category. The details drawer avoids\n * this by passing `transaction.top_level_category_guid`; the row only has the raw guid, so it is\n * walked up to its parent here (identity until categories load). That resolution applies both to a\n * `CAT-` row logo and to a merchant's `fallback_guid`. The tinted/bordered tile is opt-in per variant\n * (`tintedCategoryLogo`) and only styles the `CAT-` row branch; a merchant's `fallback_guid` is drawn\n * by `MerchantLogo`'s own untinted `CategoryIcon` fallback when the merchant image fails to load.\n */\nconst renderRowLogo = (\n row: InstanceSlotRow,\n resolveTopLevelCategory: (guid: string) => string,\n theme: Theme,\n tintedCategoryLogo: boolean,\n) => {\n const logo = logoFromRef(row.logo, row.primary_text)\n\n if (!logo) return undefined\n\n if (logo.logo_name) {\n // A `{ icon, color }` status logo (e.g. an overdraft warning) renders as a bare coloured glyph.\n // An ICO- fill logo (the Weekly New Merchants \"Others\" row - `logo_fill` is set for ICO- refs\n // only, in EntityLogo) renders as an accent tile: per the MX accent-icon pattern the background is\n // the tile colour at 15% opacity and the glyph is the full tile colour (Figma). The tile colour is\n // the logo's own colour when it carries one, else chart-2 - so tile and glyph always match.\n const accentTile = !!logo.logo_fill\n const tileColor = logo.logo_color ?? theme.palette.chart.chart2 ?? theme.palette.primary.main\n return (\n <Box\n sx={{\n alignItems: 'center',\n display: 'flex',\n height: ROW_LOGO_SIZE,\n justifyContent: 'center',\n width: ROW_LOGO_SIZE,\n ...(accentTile && {\n bgcolor: alpha(tileColor, 0.15),\n borderRadius: '8px',\n }),\n }}\n >\n <Icon\n name={logo.logo_name}\n size={ROW_ICON_SIZE}\n sx={{ color: accentTile ? tileColor : logo.logo_color }}\n />\n </Box>\n )\n }\n\n if (logo.merchant_guid) {\n return (\n <MerchantLogo\n alt={logo.merchant_name ?? ''}\n categoryGuid={logo.category_guid ? resolveTopLevelCategory(logo.category_guid) : ''}\n merchantGuid={logo.merchant_guid}\n size={ROW_LOGO_SIZE}\n />\n )\n }\n\n if (logo.institution_guid) {\n return (\n <InstitutionLogo\n alt={logo.institution_name ?? ''}\n institutionGuid={logo.institution_guid}\n size={ROW_LOGO_SIZE}\n />\n )\n }\n\n if (logo.category_guid) {\n const topLevelGuid = resolveTopLevelCategory(logo.category_guid)\n // When the variant opts in (`tintedCategoryLogo`), the tile is the Budget-style accent: the\n // category colour at 15% opacity, a 1px category-colour border, and a `text.primary` glyph\n // (Figma - Replenish Savings' multi-account Transfer row). Otherwise mxui's default tile, so other\n // beats' category logos are unchanged.\n const tintSx = tintedCategoryLogo\n ? {\n bgcolor: alpha(getCategoryColor(topLevelGuid, theme), 0.15),\n border: `1px solid ${getCategoryColor(topLevelGuid, theme)}`,\n color: 'text.primary',\n }\n : undefined\n return (\n <Box data-testid={`category-icon-${topLevelGuid}`} sx={{ display: 'flex' }}>\n <CategoryIcon categoryGuid={topLevelGuid} size={ROW_LOGO_SIZE} sx={tintSx} />\n </Box>\n )\n }\n\n return undefined\n}\n\n/**\n * The `transaction_block`: rows the backend already localized, carried inline on\n * `instance_slot.data.series` (`logo`, `primary_text`, `secondary_text`, `amount`). Only the\n * amount is formatted here, because the contract sends it as a number. `instance_slot.variant`\n * picks the header and slot treatment from `./layout.ts`.\n *\n * This is the full/mini shape. The reduced widgets (micro, embedded) resolve to the row logo\n * alone, carried flat on `data.logo` with no `series`, and are drawn by `CompactInsightCard`.\n *\n * `status_message` draws no rows: `data.message` beside the `data.icon` logo, as a\n * `StatusMessageCard` banner (Uncategorized Transactions V2 `complete`).\n *\n * A header, when the variant shows one, comes from `instance_slot.data.header_text` (the\n * transaction date, or \"{count} transactions\"). It deliberately does *not* come from the first\n * row: on a `with_merchant` card a row's `secondary_text` is the category, so reading it here\n * rendered the category twice and dropped the date entirely.\n *\n * A footer/summary row (Replenish Savings' \"Remaining Balance\", Weekly New Merchants' \"Total\")\n * renders when the variant's `showFooter` config is set (`with_header_footer`, `with_footer`), from\n * `data.footer_text` with `data.footer_amount` beside it, formatted like the row amounts (the\n * contract sends it as a number).\n */\nexport const TransactionBlock = observer(({ payload }: TransactionBlockProps) => {\n const theme = useTheme()\n const { getTopLevelCategoryGuid } = useCategoryStore()\n const stores = useGlobalStore()\n const { recurring: recurringCopy } = useGlobalCopyStore()\n const { beat } = useBeatActions()\n const { data, variant } = payload.instance_slot\n // The plain row is the safe default: it adds nothing a wrong variant could misstate.\n const {\n answeredBackground,\n background,\n cardVariant,\n creditAmounts,\n elevated,\n followsSubscription,\n headerColor,\n raised,\n showFooter,\n showFrequency,\n showHeader,\n statusMessage,\n sx,\n tintedCategoryLogo,\n } = resolveVariantConfig(\n getLayoutConfig(theme),\n variant,\n transactionBlockVariant.NoHeader,\n 'TransactionBlock',\n )\n\n // The live repeating transaction (read-only), for the frequency and the badge / answered wash.\n const repeating =\n (showFrequency || followsSubscription) && beat\n ? repeatingTransactionOf({ beat, stores })\n : undefined\n const subscribed = !!followsSubscription && repeating?.user_response === USER_RESPONSE.CONFIRMED\n\n if (statusMessage) {\n const message = slot<string>(data, 'message')\n if (typeof message !== 'string' || !message.trim()) {\n console.warn('[TransactionBlock] status_message has no message — rendering nothing.')\n return null\n }\n\n // The icon only decorates the message, so it is hidden from the status announcement.\n return (\n <StatusMessageCard\n icon={\n <Box aria-hidden=\"true\" sx={{ display: 'flex' }}>\n <LogoFromGuid logo={slot<LogoRef>(data, 'icon')} size={STATUS_ICON_SIZE} />\n </Box>\n }\n message={message}\n // The 20% wash layers over paper, as Figma's slot does.\n sx={background ? { backgroundImage: background, bgcolor: 'background.paper' } : undefined}\n />\n )\n }\n\n const series = slot<InstanceSlotRow[]>(data, 'series')\n const headerText = slot<string>(data, 'header_text')\n\n if (!Array.isArray(series) || !series.length) return null\n\n const header = showHeader && typeof headerText === 'string' ? headerText : undefined\n\n const footerText = slot<string>(data, 'footer_text')\n const footerAmount = slot<number>(data, 'footer_amount')\n const footer =\n showFooter && typeof footerText === 'string'\n ? {\n label: footerText,\n amount: formatCurrency(footerAmount, '0,0.00'),\n }\n : undefined\n\n // Live, as pulse: the repeating transaction the CTA's `prepare` loads.\n const frequency = showFrequency ? subscriptionFrequency(recurringCopy, repeating) : undefined\n const badge = followsSubscription ? (\n <SubscriptionBadge icon={slot<LogoRef>(data, subscribed ? 'reviewed_icon' : 'icon')} />\n ) : undefined\n\n // Only a positive amount reads as a credit.\n const isCredit = (amount: unknown) => !!creditAmounts && typeof amount === 'number' && amount > 0\n\n return (\n <TransactionListCard\n background={subscribed && answeredBackground ? answeredBackground : background}\n badge={badge}\n elevated={elevated}\n footer={footer}\n header={header}\n headerColor={headerColor}\n raised={raised}\n sx={sx}\n variant={cardVariant}\n rows={series.map((row) => ({\n amount:\n typeof row.amount === 'number'\n ? `${isCredit(row.amount) ? '+' : ''}${formatCurrency(row.amount, '0,0.00')}`\n : '',\n amountColor: isCredit(row.amount) ? 'success.main' : undefined,\n amountCaption: frequency,\n leading: renderRowLogo(row, getTopLevelCategoryGuid, theme, tintedCategoryLogo ?? false),\n subtitle: row.secondary_text ?? '',\n title: row.primary_text ?? '',\n }))}\n />\n )\n})\n"],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ import { SxProps, Theme } from '@mui/material/styles';
|
|
|
16
16
|
* (Uncategorized Transactions V2 `complete`, "All Categorized!").
|
|
17
17
|
* - `SpendingSummary` — header, rows and footer, with the header text in `primary.main`
|
|
18
18
|
* (Weekend Spending Summary: the weekend above one row per category and "Total spent").
|
|
19
|
+
* - `DepositList` — the date above the rows, each amount a green "+" credit (Micro Deposits).
|
|
19
20
|
*/
|
|
20
21
|
export declare const transactionBlockVariant: {
|
|
21
22
|
readonly WithHeader: "with_header";
|
|
@@ -27,6 +28,7 @@ export declare const transactionBlockVariant: {
|
|
|
27
28
|
readonly WarningWash: "warning_wash";
|
|
28
29
|
readonly StatusMessage: "status_message";
|
|
29
30
|
readonly SpendingSummary: "spending_summary";
|
|
31
|
+
readonly DepositList: "deposit_list";
|
|
30
32
|
};
|
|
31
33
|
export type TransactionBlockVariant = (typeof transactionBlockVariant)[keyof typeof transactionBlockVariant];
|
|
32
34
|
export interface TransactionLayoutConfig {
|
|
@@ -61,6 +63,8 @@ export interface TransactionLayoutConfig {
|
|
|
61
63
|
* every `transaction_block` consumer.
|
|
62
64
|
*/
|
|
63
65
|
tintedCategoryLogo?: boolean;
|
|
66
|
+
/** Draw each amount as a credit: a "+" prefix in `success.main`. */
|
|
67
|
+
creditAmounts?: boolean;
|
|
64
68
|
}
|
|
65
69
|
/** Per-variant `TransactionListCard` props (mirrors DetailedAccountBlock's `getLayoutConfig`). */
|
|
66
70
|
export declare const getLayoutConfig: (theme: Theme) => Record<TransactionBlockVariant, TransactionLayoutConfig>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WARM_LIME_ACCENT_GRADIENT as r, WARNING_WASH_GRADIENT as
|
|
1
|
+
import { WARM_LIME_ACCENT_GRADIENT as r, WARNING_WASH_GRADIENT as t, getPrimaryWashGradient as o } from "../../../components/celebrationGradients.es.js";
|
|
2
2
|
var e = {
|
|
3
3
|
WithHeader: "with_header",
|
|
4
4
|
WithHeaderFooter: "with_header_footer",
|
|
@@ -8,8 +8,9 @@ var e = {
|
|
|
8
8
|
InfoWash: "info_wash",
|
|
9
9
|
WarningWash: "warning_wash",
|
|
10
10
|
StatusMessage: "status_message",
|
|
11
|
-
SpendingSummary: "spending_summary"
|
|
12
|
-
|
|
11
|
+
SpendingSummary: "spending_summary",
|
|
12
|
+
DepositList: "deposit_list"
|
|
13
|
+
}, i = (a) => ({
|
|
13
14
|
[e.WithHeader]: {
|
|
14
15
|
showHeader: !0,
|
|
15
16
|
tintedCategoryLogo: !0
|
|
@@ -29,13 +30,13 @@ var e = {
|
|
|
29
30
|
},
|
|
30
31
|
[e.InfoWash]: {
|
|
31
32
|
showHeader: !1,
|
|
32
|
-
background:
|
|
33
|
+
background: o(a),
|
|
33
34
|
raised: !0,
|
|
34
35
|
showFrequency: !0
|
|
35
36
|
},
|
|
36
37
|
[e.WarningWash]: {
|
|
37
38
|
showHeader: !1,
|
|
38
|
-
background:
|
|
39
|
+
background: t,
|
|
39
40
|
showFrequency: !0,
|
|
40
41
|
followsSubscription: !0,
|
|
41
42
|
answeredBackground: r,
|
|
@@ -51,10 +52,15 @@ var e = {
|
|
|
51
52
|
showHeader: !0,
|
|
52
53
|
showFooter: !0,
|
|
53
54
|
headerColor: "primary.main"
|
|
55
|
+
},
|
|
56
|
+
[e.DepositList]: {
|
|
57
|
+
showHeader: !0,
|
|
58
|
+
tintedCategoryLogo: !0,
|
|
59
|
+
creditAmounts: !0
|
|
54
60
|
}
|
|
55
61
|
});
|
|
56
62
|
export {
|
|
57
|
-
|
|
63
|
+
i as getLayoutConfig,
|
|
58
64
|
e as transactionBlockVariant
|
|
59
65
|
};
|
|
60
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.ts"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material/styles'\n\nimport {\n WARM_LIME_ACCENT_GRADIENT,\n WARNING_WASH_GRADIENT,\n getPrimaryWashGradient,\n} from '../../../components/celebrationGradients'\n\n/**\n * Transaction block variants, keyed by the backend `instance_slot.variant`. All render the same\n * pre-localized rows through `TransactionListCard`; only the header and the slot differ.\n *\n * - `WithHeader` — row under a date header (Fee Detected, Large Transaction).\n * - `WithHeaderFooter` — date header above the rows plus the footer/summary row from\n * `data.footer_text` / `data.footer_amount` (Replenish Savings' \"Remaining Balance\").\n * - `NoHeader` — the row alone (Large Transaction without a merchant).\n * - `UncategorizedTransaction` — filled primary header (\"{count} transactions\").\n * - `InfoWash` — raised row (border + shadow) on the blue slot wash, with the\n * subscription's live frequency under the amount (e.g. Subscription Detected).\n * - `WarningWash` — borderless row on the warning slot wash (e.g. Unexpected\n * Subscription Payment). Treatment names, not beat names, so any beat can reuse the wash.\n * - `StatusMessage` — no rows: an icon + message banner from `data.icon` / `data.message`\n * (Uncategorized Transactions V2 `complete`, \"All Categorized!\").\n * - `SpendingSummary` — header, rows and footer, with the header text in `primary.main`\n * (Weekend Spending Summary: the weekend above one row per category and \"Total spent\").\n */\nexport const transactionBlockVariant = {\n WithHeader: 'with_header',\n WithHeaderFooter: 'with_header_footer',\n NoHeader: 'no_header',\n // A multi-row list with no in-card header plus a \"Total\" summary row (Weekly New Merchants; the\n // date range is the card subtitle). The plain no-footer list reuses `NoHeader`.\n WithFooter: 'with_footer',\n UncategorizedTransaction: 'uncategorized_transaction',\n InfoWash: 'info_wash',\n WarningWash: 'warning_wash',\n StatusMessage: 'status_message',\n SpendingSummary: 'spending_summary',\n} as const\n\nexport type TransactionBlockVariant =\n (typeof transactionBlockVariant)[keyof typeof transactionBlockVariant]\n\nexport interface TransactionLayoutConfig {\n /** Show `instance_slot.data.header_text` above the rows. */\n showHeader: boolean\n /** Show the `data.footer_text` / `data.footer_amount` summary row beneath the rows. */\n showFooter?: boolean\n /** `TransactionListCard` style: grey utility header, or filled primary header. */\n cardVariant?: 'default' | 'primary'\n /** Theme colour for the header text, over the card style's own. */\n headerColor?: string\n /** CSS background for the slot behind the card; the card renders borderless unless `raised`. */\n background?: string\n /** Render `data.message` as a `StatusMessageCard` banner instead of the rows. */\n statusMessage?: boolean\n /** Caption each amount with the beat's live repeating transaction frequency. */\n showFrequency?: boolean\n /** Status badge and answered wash from the live repeating transaction. */\n followsSubscription?: boolean\n /** Wash once subscribed. */\n answeredBackground?: string\n /** Row card at `elevation/1` (needs `background`). */\n elevated?: boolean\n /** Slot padding override (CSS shorthand). */\n sx?: SxProps\n /** Border and shadow on the row card. */\n raised?: boolean\n /**\n * Tint a `CAT-` row logo as the Budget-style accent tile (category colour at 15% opacity, a 1px\n * category-colour border, a `text.primary` glyph) instead of mxui's default. Opt-in per variant so\n * it stays scoped to the beats that want it (Replenish Savings' multi-account Transfer row), not\n * every `transaction_block` consumer.\n */\n tintedCategoryLogo?: boolean\n}\n\n/** Per-variant `TransactionListCard` props (mirrors DetailedAccountBlock's `getLayoutConfig`). */\nexport const getLayoutConfig = (\n theme: Theme,\n): Record<TransactionBlockVariant, TransactionLayoutConfig> => ({\n // `with_header` is Replenish Savings' multi-account card: its one summary row is a `CAT-` Transfer\n // logo, which we tint. (Other `with_header` beats, e.g. Large Transaction, use a merchant logo, so\n // the `CAT-` tint path never runs for them.)\n [transactionBlockVariant.WithHeader]: { showHeader: true, tintedCategoryLogo: true },\n [transactionBlockVariant.WithHeaderFooter]: { showHeader: true, showFooter: true },\n [transactionBlockVariant.NoHeader]: { showHeader: false },\n [transactionBlockVariant.WithFooter]: { showHeader: false, showFooter: true },\n [transactionBlockVariant.UncategorizedTransaction]: { showHeader: true, cardVariant: 'primary' },\n [transactionBlockVariant.InfoWash]: {\n showHeader: false,\n background: getPrimaryWashGradient(theme),\n raised: true,\n showFrequency: true,\n },\n [transactionBlockVariant.WarningWash]: {\n showHeader: false,\n background: WARNING_WASH_GRADIENT,\n showFrequency: true,\n followsSubscription: true,\n answeredBackground: WARM_LIME_ACCENT_GRADIENT,\n elevated: true,\n // Room for the badge.\n sx: { p: '28px 24px 24px 32px' },\n },\n // Figma 1941:207336: the banner sits on the warm-to-lime slot wash.\n [transactionBlockVariant.StatusMessage]: {\n showHeader: false,\n statusMessage: true,\n background: WARM_LIME_ACCENT_GRADIENT,\n },\n [transactionBlockVariant.SpendingSummary]: {\n showHeader: true,\n showFooter: true,\n headerColor: 'primary.main',\n },\n})\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"layout.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.ts"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material/styles'\n\nimport {\n WARM_LIME_ACCENT_GRADIENT,\n WARNING_WASH_GRADIENT,\n getPrimaryWashGradient,\n} from '../../../components/celebrationGradients'\n\n/**\n * Transaction block variants, keyed by the backend `instance_slot.variant`. All render the same\n * pre-localized rows through `TransactionListCard`; only the header and the slot differ.\n *\n * - `WithHeader` — row under a date header (Fee Detected, Large Transaction).\n * - `WithHeaderFooter` — date header above the rows plus the footer/summary row from\n * `data.footer_text` / `data.footer_amount` (Replenish Savings' \"Remaining Balance\").\n * - `NoHeader` — the row alone (Large Transaction without a merchant).\n * - `UncategorizedTransaction` — filled primary header (\"{count} transactions\").\n * - `InfoWash` — raised row (border + shadow) on the blue slot wash, with the\n * subscription's live frequency under the amount (e.g. Subscription Detected).\n * - `WarningWash` — borderless row on the warning slot wash (e.g. Unexpected\n * Subscription Payment). Treatment names, not beat names, so any beat can reuse the wash.\n * - `StatusMessage` — no rows: an icon + message banner from `data.icon` / `data.message`\n * (Uncategorized Transactions V2 `complete`, \"All Categorized!\").\n * - `SpendingSummary` — header, rows and footer, with the header text in `primary.main`\n * (Weekend Spending Summary: the weekend above one row per category and \"Total spent\").\n * - `DepositList` — the date above the rows, each amount a green \"+\" credit (Micro Deposits).\n */\nexport const transactionBlockVariant = {\n WithHeader: 'with_header',\n WithHeaderFooter: 'with_header_footer',\n NoHeader: 'no_header',\n // A multi-row list with no in-card header plus a \"Total\" summary row (Weekly New Merchants; the\n // date range is the card subtitle). The plain no-footer list reuses `NoHeader`.\n WithFooter: 'with_footer',\n UncategorizedTransaction: 'uncategorized_transaction',\n InfoWash: 'info_wash',\n WarningWash: 'warning_wash',\n StatusMessage: 'status_message',\n SpendingSummary: 'spending_summary',\n DepositList: 'deposit_list',\n} as const\n\nexport type TransactionBlockVariant =\n (typeof transactionBlockVariant)[keyof typeof transactionBlockVariant]\n\nexport interface TransactionLayoutConfig {\n /** Show `instance_slot.data.header_text` above the rows. */\n showHeader: boolean\n /** Show the `data.footer_text` / `data.footer_amount` summary row beneath the rows. */\n showFooter?: boolean\n /** `TransactionListCard` style: grey utility header, or filled primary header. */\n cardVariant?: 'default' | 'primary'\n /** Theme colour for the header text, over the card style's own. */\n headerColor?: string\n /** CSS background for the slot behind the card; the card renders borderless unless `raised`. */\n background?: string\n /** Render `data.message` as a `StatusMessageCard` banner instead of the rows. */\n statusMessage?: boolean\n /** Caption each amount with the beat's live repeating transaction frequency. */\n showFrequency?: boolean\n /** Status badge and answered wash from the live repeating transaction. */\n followsSubscription?: boolean\n /** Wash once subscribed. */\n answeredBackground?: string\n /** Row card at `elevation/1` (needs `background`). */\n elevated?: boolean\n /** Slot padding override (CSS shorthand). */\n sx?: SxProps\n /** Border and shadow on the row card. */\n raised?: boolean\n /**\n * Tint a `CAT-` row logo as the Budget-style accent tile (category colour at 15% opacity, a 1px\n * category-colour border, a `text.primary` glyph) instead of mxui's default. Opt-in per variant so\n * it stays scoped to the beats that want it (Replenish Savings' multi-account Transfer row), not\n * every `transaction_block` consumer.\n */\n tintedCategoryLogo?: boolean\n /** Draw each amount as a credit: a \"+\" prefix in `success.main`. */\n creditAmounts?: boolean\n}\n\n/** Per-variant `TransactionListCard` props (mirrors DetailedAccountBlock's `getLayoutConfig`). */\nexport const getLayoutConfig = (\n theme: Theme,\n): Record<TransactionBlockVariant, TransactionLayoutConfig> => ({\n // `with_header` is Replenish Savings' multi-account card: its one summary row is a `CAT-` Transfer\n // logo, which we tint. (Other `with_header` beats, e.g. Large Transaction, use a merchant logo, so\n // the `CAT-` tint path never runs for them.)\n [transactionBlockVariant.WithHeader]: { showHeader: true, tintedCategoryLogo: true },\n [transactionBlockVariant.WithHeaderFooter]: { showHeader: true, showFooter: true },\n [transactionBlockVariant.NoHeader]: { showHeader: false },\n [transactionBlockVariant.WithFooter]: { showHeader: false, showFooter: true },\n [transactionBlockVariant.UncategorizedTransaction]: { showHeader: true, cardVariant: 'primary' },\n [transactionBlockVariant.InfoWash]: {\n showHeader: false,\n background: getPrimaryWashGradient(theme),\n raised: true,\n showFrequency: true,\n },\n [transactionBlockVariant.WarningWash]: {\n showHeader: false,\n background: WARNING_WASH_GRADIENT,\n showFrequency: true,\n followsSubscription: true,\n answeredBackground: WARM_LIME_ACCENT_GRADIENT,\n elevated: true,\n // Room for the badge.\n sx: { p: '28px 24px 24px 32px' },\n },\n // Figma 1941:207336: the banner sits on the warm-to-lime slot wash.\n [transactionBlockVariant.StatusMessage]: {\n showHeader: false,\n statusMessage: true,\n background: WARM_LIME_ACCENT_GRADIENT,\n },\n [transactionBlockVariant.SpendingSummary]: {\n showHeader: true,\n showFooter: true,\n headerColor: 'primary.main',\n },\n [transactionBlockVariant.DepositList]: {\n showHeader: true,\n tintedCategoryLogo: true,\n creditAmounts: true,\n },\n})\n"],"mappings":";AA2BA,IAAa,IAA0B;AAAA,EACrC,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,UAAU;AAAA,EAGV,YAAY;AAAA,EACZ,0BAA0B;AAAA,EAC1B,UAAU;AAAA,EACV,aAAa;AAAA,EACb,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,aAAa;AACf,GA0Ca,IAAA,CACX,OAC8D;AAAA,EAI7D,CAAA,EAAwB,UAAA,GAAa;AAAA,IAAE,YAAY;AAAA,IAAM,oBAAoB;AAAA,EAAK;AAAA,EAClF,CAAA,EAAwB,gBAAA,GAAmB;AAAA,IAAE,YAAY;AAAA,IAAM,YAAY;AAAA,EAAK;AAAA,EAChF,CAAA,EAAwB,QAAA,GAAW,EAAE,YAAY,GAAM;AAAA,EACvD,CAAA,EAAwB,UAAA,GAAa;AAAA,IAAE,YAAY;AAAA,IAAO,YAAY;AAAA,EAAK;AAAA,EAC3E,CAAA,EAAwB,wBAAA,GAA2B;AAAA,IAAE,YAAY;AAAA,IAAM,aAAa;AAAA,EAAU;AAAA,EAC9F,CAAA,EAAwB,QAAA,GAAW;AAAA,IAClC,YAAY;AAAA,IACZ,YAAY,EAAuB,CAAK;AAAA,IACxC,QAAQ;AAAA,IACR,eAAe;AAAA,EACjB;AAAA,EACC,CAAA,EAAwB,WAAA,GAAc;AAAA,IACrC,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,qBAAqB;AAAA,IACrB,oBAAoB;AAAA,IACpB,UAAU;AAAA,IAEV,IAAI,EAAE,GAAG,sBAAsB;AAAA,EACjC;AAAA,EAEC,CAAA,EAAwB,aAAA,GAAgB;AAAA,IACvC,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,YAAY;AAAA,EACd;AAAA,EACC,CAAA,EAAwB,eAAA,GAAkB;AAAA,IACzC,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAAA,EACC,CAAA,EAAwB,WAAA,GAAc;AAAA,IACrC,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,eAAe;AAAA,EACjB;AACF"}
|