@mx-cartographer/experiences 9.3.3 → 9.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [9.3.4] - 08-12-2026
|
|
2
|
+
|
|
3
|
+
- **FIXED** - Blank rows in "Manage Insights Notifications": 10 members of `InsightNotificationTypes` were rendered by the settings list but had no entry in `getProfileLabel`'s `labelMap`, so they displayed a working, toggleable notification row with an empty title (MEW2-2872)
|
|
4
|
+
- **ADDED** - `category_budget`, `goal_progress`, `spending_plan_budget_exceeded`, and `spending_plan_category_spending` settings copy keys; the other six newly-labeled types reuse existing copy
|
|
5
|
+
- **ADDED** - `src/core/utils/__tests__/SettingsUtil.test.ts` asserting every `InsightNotificationTypes` member resolves to a non-empty label, so enum/label-map drift fails CI instead of shipping a blank row
|
|
6
|
+
|
|
1
7
|
## [9.3.3] - 08-11-2026
|
|
2
8
|
|
|
3
9
|
- **FIXED** - Exported transaction CSV showed the post date one day early for users in Western (negative-offset) timezones because the date was rendered from the raw epoch in local time; the Date column now uses the UTC calendar day (MEW-3961)
|
|
@@ -28,6 +34,7 @@
|
|
|
28
34
|
- **CHANGED** - Pinned `msw` to an exact `2.15.0` to match the vendored `mockServiceWorker.js`, and `Beats.js` → `Beats.ts`
|
|
29
35
|
- **ADDED** - `src/core/api/__tests__/ApiClasses.test.ts` exercising the real `src/core/api/*` classes against MSW; coverage now includes `src/core/api/**` in the denominator (the MSW migration runs the real API classes) with the REVIEW.md floors kept at lines 85 / statements 85 / functions 80 / branches 78 (tests added to clear them rather than lowering), and `coverage.cleanOnRerun` set to `true` so a re-run can't satisfy the floors with stale data
|
|
30
36
|
- **CHANGED** - Dependency/structure hygiene: removed the unused `path` userland shim (configs use `node:path`); documented why `@typescript/typescript6` is retained (vite-plugin-dts needs the JS Compiler API that TS 7 native doesn't yet expose); consolidated the root `mockData/` fixtures into `mock/data/`
|
|
37
|
+
|
|
31
38
|
## [9.2.9] - 08-09-2026
|
|
32
39
|
|
|
33
40
|
- **FIXED** - Category selector drawer kept the previously expanded accordion and highlighted selection when reopened for a different transaction; it now resets and expands to the current transaction's category each time it opens
|
|
@@ -113,11 +113,13 @@ export interface SettingsCopy {
|
|
|
113
113
|
large_transaction: string;
|
|
114
114
|
account_balance_low: string;
|
|
115
115
|
bill_amount_not_standard: string;
|
|
116
|
+
category_budget: string;
|
|
116
117
|
category_spending: string;
|
|
117
118
|
credit_card_close_to_limit: string;
|
|
118
119
|
debt_payment_reminder: string;
|
|
119
120
|
debt_payment_reminder_v3: string;
|
|
120
121
|
duplicate_payment: string;
|
|
122
|
+
goal_progress: string;
|
|
121
123
|
monthly_spend_comparison: string;
|
|
122
124
|
monthly_spend_to_income_comparison: string;
|
|
123
125
|
monthly_subscription_aggregate: string;
|
|
@@ -125,6 +127,8 @@ export interface SettingsCopy {
|
|
|
125
127
|
save_an_extra_100_dollars: string;
|
|
126
128
|
savings_opportunity: string;
|
|
127
129
|
set_up_direct_deposit: string;
|
|
130
|
+
spending_plan_budget_exceeded: string;
|
|
131
|
+
spending_plan_category_spending: string;
|
|
128
132
|
switch_direct_deposit: string;
|
|
129
133
|
uncategorized_transactions: string;
|
|
130
134
|
unified_deposit: string;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { Account, ClientCommunicationProfile, DetailedNotificationProfile, NotificationProfile, SettingsCopy, User, UserCommunicationProfile } from '../types';
|
|
2
|
+
export declare const PARENT_ENTITY = "PARENT-ENTITY";
|
|
2
3
|
export declare const augmentNotificationProfiles: (accounts: Account[], clientCommunicationsProfile: ClientCommunicationProfile, copy: SettingsCopy, profiles: NotificationProfile[], userCommunicationsProfile: UserCommunicationProfile, user: User) => DetailedNotificationProfile[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AccountNotificationTypes as n, BudgetNotificationTypes as u, InsightNotificationTypes as t } from "../types/Notification.es.js";
|
|
2
|
-
var
|
|
2
|
+
var P = "PARENT-ENTITY", S = (o, e) => ({
|
|
3
3
|
[u.BudgetExceeded]: e.notification_budget_exceeded,
|
|
4
4
|
[u.BudgetOffTarget]: e.notification_budget_off_target,
|
|
5
5
|
[n.DebtPaymentReminder]: e.notification_debt_payment_reminder,
|
|
@@ -10,11 +10,17 @@ var g = "PARENT-ENTITY", D = (o, e) => ({
|
|
|
10
10
|
[n.TransactionFeeCharge]: e.notification_transaction_fee,
|
|
11
11
|
[n.InternationalTransaction]: e.notification_transaction_is_international,
|
|
12
12
|
[t.AccountBalanceLow]: e.account_balance_low,
|
|
13
|
+
[t.AccountDepositHigh]: e.notification_large_deposit,
|
|
13
14
|
[t.BillAmountNotStandard]: e.bill_amount_not_standard,
|
|
15
|
+
[t.BudgetExceeded]: e.notification_budget_exceeded,
|
|
16
|
+
[t.BudgetOffTarget]: e.notification_budget_off_target,
|
|
17
|
+
[t.CategoryBudget]: e.category_budget,
|
|
14
18
|
[t.CategorySpending]: e.category_spending,
|
|
15
19
|
[t.CreditCardCloseToLimit]: e.credit_card_close_to_limit,
|
|
16
20
|
[t.DebtPaymentReminder]: e.debt_payment_reminder,
|
|
21
|
+
[t.DebtPaymentReminderV3]: e.debt_payment_reminder_v3,
|
|
17
22
|
[t.DuplicatePayment]: e.duplicate_payment,
|
|
23
|
+
[t.GoalProgress]: e.goal_progress,
|
|
18
24
|
[t.MonthlySpendComparison]: e.monthly_spend_comparison,
|
|
19
25
|
[t.MonthlySpendToIncomeComparison]: e.monthly_spend_to_income_comparison,
|
|
20
26
|
[t.MonthlySubscriptionAggregate]: e.monthly_subscription_aggregate,
|
|
@@ -22,7 +28,11 @@ var g = "PARENT-ENTITY", D = (o, e) => ({
|
|
|
22
28
|
[t.SaveAnExtra100Dollars]: e.save_an_extra_100_dollars,
|
|
23
29
|
[t.SavingsOpportunity]: e.savings_opportunity,
|
|
24
30
|
[t.SetUpDirectDeposit]: e.set_up_direct_deposit,
|
|
31
|
+
[t.SpendingPlanBudgetExceeded]: e.spending_plan_budget_exceeded,
|
|
32
|
+
[t.SpendingPlanCategorySpending]: e.spending_plan_category_spending,
|
|
25
33
|
[t.SwitchDirectDeposit]: e.switch_direct_deposit,
|
|
34
|
+
[t.TransactionFeeCharge]: e.notification_transaction_fee,
|
|
35
|
+
[t.TransactionIsInternational]: e.notification_transaction_is_international,
|
|
26
36
|
[t.UncategorizedTransactions]: e.uncategorized_transactions,
|
|
27
37
|
[t.UnifiedDeposit]: e.unified_deposit,
|
|
28
38
|
[t.UpcomingBill]: e.upcoming_bill,
|
|
@@ -32,24 +42,25 @@ var g = "PARENT-ENTITY", D = (o, e) => ({
|
|
|
32
42
|
[t.TransactionExpenseLarge]: e.large_transaction,
|
|
33
43
|
[t.PromotionalCampaignMessages]: e.promotional_campaign_messages,
|
|
34
44
|
[t.TransparentOverdraft]: e.transparent_overdraft
|
|
35
|
-
})[o] || "", A = (o, e,
|
|
36
|
-
const
|
|
37
|
-
for (const i of l.filter((
|
|
38
|
-
const
|
|
39
|
-
|
|
45
|
+
})[o] || "", A = (o, e, _, l, m, g) => {
|
|
46
|
+
const c = [], { email_notifications_enabled: f, sms_notifications_enabled: p, push_notifications_enabled: h } = e, { opted_out_of_email_notifications: b, opted_out_of_sms_notifications: T, opted_out_of_push_notifications: v } = m;
|
|
47
|
+
for (const i of l.filter((r) => r.entity_guid === P)) {
|
|
48
|
+
const r = S(i.notification_type, _), E = l.filter((a) => a.entity_guid !== "PARENT-ENTITY" && a.notification_type === i.notification_type && o.some((d) => d.guid === a.entity_guid)), s = [];
|
|
49
|
+
f && !b && i.email_channel && g.email && s.push(_.delivery_method_email_label), p && !T && i.sms_channel && g.phone && s.push(_.delivery_method_sms_label), h && !v && i.push_channel && s.push(_.delivery_method_push_label), c.push({
|
|
40
50
|
...i,
|
|
41
51
|
children: E.map((a) => ({
|
|
42
52
|
...a,
|
|
43
53
|
account: o.find((d) => d.guid === a.entity_guid),
|
|
44
|
-
label:
|
|
54
|
+
label: r
|
|
45
55
|
})),
|
|
46
|
-
deliveryMethodsLabel:
|
|
47
|
-
label:
|
|
56
|
+
deliveryMethodsLabel: s.join(", "),
|
|
57
|
+
label: r
|
|
48
58
|
});
|
|
49
59
|
}
|
|
50
|
-
return
|
|
60
|
+
return c;
|
|
51
61
|
};
|
|
52
62
|
export {
|
|
63
|
+
P as PARENT_ENTITY,
|
|
53
64
|
A as augmentNotificationProfiles
|
|
54
65
|
};
|
|
55
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsUtil.es.js","names":[],"sources":["../../../src/core/utils/SettingsUtil.ts"],"sourcesContent":["import {\n type Account,\n type ClientCommunicationProfile,\n type DetailedNotificationProfile,\n type NotificationProfile,\n type SettingsCopy,\n type User,\n type UserCommunicationProfile,\n AccountNotificationTypes,\n BudgetNotificationTypes,\n InsightNotificationTypes,\n} from '../types'\n\
|
|
1
|
+
{"version":3,"file":"SettingsUtil.es.js","names":[],"sources":["../../../src/core/utils/SettingsUtil.ts"],"sourcesContent":["import {\n type Account,\n type ClientCommunicationProfile,\n type DetailedNotificationProfile,\n type NotificationProfile,\n type SettingsCopy,\n type User,\n type UserCommunicationProfile,\n AccountNotificationTypes,\n BudgetNotificationTypes,\n InsightNotificationTypes,\n} from '../types'\n\nexport const PARENT_ENTITY = 'PARENT-ENTITY'\n\nconst getProfileLabel = (notificationType: number, copy: SettingsCopy) => {\n const labelMap: Record<number, string> = {\n [BudgetNotificationTypes.BudgetExceeded]: copy.notification_budget_exceeded,\n [BudgetNotificationTypes.BudgetOffTarget]: copy.notification_budget_off_target,\n [AccountNotificationTypes.DebtPaymentReminder]: copy.notification_debt_payment_reminder,\n [AccountNotificationTypes.AccountBalanceLow]: copy.notification_low_balance,\n [AccountNotificationTypes.AccountDepositLargePosted]: copy.notification_large_deposit,\n [AccountNotificationTypes.AccountDepositLarge]: copy.notification_large_deposit,\n [AccountNotificationTypes.TransactionExpenseLarge]: copy.notification_large_expense,\n [AccountNotificationTypes.TransactionFeeCharge]: copy.notification_transaction_fee,\n [AccountNotificationTypes.InternationalTransaction]:\n copy.notification_transaction_is_international,\n [InsightNotificationTypes.AccountBalanceLow]: copy.account_balance_low,\n [InsightNotificationTypes.AccountDepositHigh]: copy.notification_large_deposit,\n [InsightNotificationTypes.BillAmountNotStandard]: copy.bill_amount_not_standard,\n [InsightNotificationTypes.BudgetExceeded]: copy.notification_budget_exceeded,\n [InsightNotificationTypes.BudgetOffTarget]: copy.notification_budget_off_target,\n [InsightNotificationTypes.CategoryBudget]: copy.category_budget,\n [InsightNotificationTypes.CategorySpending]: copy.category_spending,\n [InsightNotificationTypes.CreditCardCloseToLimit]: copy.credit_card_close_to_limit,\n [InsightNotificationTypes.DebtPaymentReminder]: copy.debt_payment_reminder,\n [InsightNotificationTypes.DebtPaymentReminderV3]: copy.debt_payment_reminder_v3,\n [InsightNotificationTypes.DuplicatePayment]: copy.duplicate_payment,\n [InsightNotificationTypes.GoalProgress]: copy.goal_progress,\n [InsightNotificationTypes.MonthlySpendComparison]: copy.monthly_spend_comparison,\n [InsightNotificationTypes.MonthlySpendToIncomeComparison]:\n copy.monthly_spend_to_income_comparison,\n [InsightNotificationTypes.MonthlySubscriptionAggregate]: copy.monthly_subscription_aggregate,\n [InsightNotificationTypes.MonthlyTopMerchantSpending]: copy.monthly_top_merchant_spending,\n [InsightNotificationTypes.SaveAnExtra100Dollars]: copy.save_an_extra_100_dollars,\n [InsightNotificationTypes.SavingsOpportunity]: copy.savings_opportunity,\n [InsightNotificationTypes.SetUpDirectDeposit]: copy.set_up_direct_deposit,\n [InsightNotificationTypes.SpendingPlanBudgetExceeded]: copy.spending_plan_budget_exceeded,\n [InsightNotificationTypes.SpendingPlanCategorySpending]: copy.spending_plan_category_spending,\n [InsightNotificationTypes.SwitchDirectDeposit]: copy.switch_direct_deposit,\n [InsightNotificationTypes.TransactionFeeCharge]: copy.notification_transaction_fee,\n [InsightNotificationTypes.TransactionIsInternational]:\n copy.notification_transaction_is_international,\n [InsightNotificationTypes.UncategorizedTransactions]: copy.uncategorized_transactions,\n [InsightNotificationTypes.UnifiedDeposit]: copy.unified_deposit,\n [InsightNotificationTypes.UpcomingBill]: copy.upcoming_bill,\n [InsightNotificationTypes.WeekendSpendingSummary]: copy.weekend_spending_summary,\n [InsightNotificationTypes.WeeklyNewMerchants]: copy.weekly_new_merchants,\n [InsightNotificationTypes.DiscoveredAccounts]: copy.discovered_account,\n [InsightNotificationTypes.TransactionExpenseLarge]: copy.large_transaction,\n [InsightNotificationTypes.PromotionalCampaignMessages]: copy.promotional_campaign_messages,\n [InsightNotificationTypes.TransparentOverdraft]: copy.transparent_overdraft,\n }\n\n return labelMap[notificationType] || ''\n}\n\nexport const augmentNotificationProfiles = (\n accounts: Account[],\n clientCommunicationsProfile: ClientCommunicationProfile,\n copy: SettingsCopy,\n profiles: NotificationProfile[],\n userCommunicationsProfile: UserCommunicationProfile,\n user: User,\n) => {\n const detailedProfiles = [] as DetailedNotificationProfile[]\n const {\n email_notifications_enabled: clientEmailEnabled,\n sms_notifications_enabled: clientSmsEnabled,\n push_notifications_enabled: clientPushEnabled,\n } = clientCommunicationsProfile\n\n const {\n opted_out_of_email_notifications: userEmailOptedOut,\n opted_out_of_sms_notifications: userSmsOptedOut,\n opted_out_of_push_notifications: userPushOptedOut,\n } = userCommunicationsProfile\n\n for (const profile of profiles.filter((profile) => profile.entity_guid === PARENT_ENTITY)) {\n const label = getProfileLabel(profile.notification_type, copy)\n const children = profiles.filter(\n (child) =>\n child.entity_guid !== PARENT_ENTITY &&\n child.notification_type === profile.notification_type &&\n accounts.some((account) => account.guid === child.entity_guid),\n )\n\n const deliveryMethods = [] as string[]\n if (clientEmailEnabled && !userEmailOptedOut && profile.email_channel && user.email) {\n deliveryMethods.push(copy.delivery_method_email_label)\n }\n if (clientSmsEnabled && !userSmsOptedOut && profile.sms_channel && user.phone) {\n deliveryMethods.push(copy.delivery_method_sms_label)\n }\n if (clientPushEnabled && !userPushOptedOut && profile.push_channel) {\n deliveryMethods.push(copy.delivery_method_push_label)\n }\n\n detailedProfiles.push({\n ...profile,\n children: children.map((child) => ({\n ...child,\n account: accounts.find((a) => a.guid === child.entity_guid),\n label,\n })),\n deliveryMethodsLabel: deliveryMethods.join(', '),\n label,\n })\n }\n\n return detailedProfiles\n}\n"],"mappings":"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"}
|