@mx-cartographer/experiences 9.4.1 → 9.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/budgets/BubbleBudgetsWidget.es.js +29 -29
  3. package/dist/budgets/BubbleBudgetsWidget.es.js.map +1 -1
  4. package/dist/budgets/components/AddBudgets.es.js +16 -13
  5. package/dist/budgets/components/AddBudgets.es.js.map +1 -1
  6. package/dist/budgets/components/BudgetDetailsDrawer.es.js +129 -91
  7. package/dist/budgets/components/BudgetDetailsDrawer.es.js.map +1 -1
  8. package/dist/budgets/components/BudgetDetailsDrawerV2.es.js +16 -13
  9. package/dist/budgets/components/BudgetDetailsDrawerV2.es.js.map +1 -1
  10. package/dist/budgets/components/addbudget/RecalculateBudgets.es.js +14 -11
  11. package/dist/budgets/components/addbudget/RecalculateBudgets.es.js.map +1 -1
  12. package/dist/budgets/components/budgetdetails/AddSubBudget.es.js +58 -55
  13. package/dist/budgets/components/budgetdetails/AddSubBudget.es.js.map +1 -1
  14. package/dist/budgets/components/budgetdetails/BudgetDetails.es.js +8 -5
  15. package/dist/budgets/components/budgetdetails/BudgetDetails.es.js.map +1 -1
  16. package/dist/budgets/components/budgetdetails/SubBudgetAmounts.d.ts +9 -0
  17. package/dist/budgets/components/budgetdetails/SubBudgetAmounts.es.js +69 -0
  18. package/dist/budgets/components/budgetdetails/SubBudgetAmounts.es.js.map +1 -0
  19. package/dist/budgets/components/budgetdetails/SubBudgetList.es.js +68 -55
  20. package/dist/budgets/components/budgetdetails/SubBudgetList.es.js.map +1 -1
  21. package/dist/budgets/components/budgetlist/BudgetRow.es.js +15 -26
  22. package/dist/budgets/components/budgetlist/BudgetRow.es.js.map +1 -1
  23. package/dist/budgets/components/budgetlist/SubBudgetRow.es.js +12 -55
  24. package/dist/budgets/components/budgetlist/SubBudgetRow.es.js.map +1 -1
  25. package/dist/budgets/components/shared/BudgetAmount.es.js +14 -15
  26. package/dist/budgets/components/shared/BudgetAmount.es.js.map +1 -1
  27. package/dist/budgets/components/shared/BudgetDonut.d.ts +8 -0
  28. package/dist/budgets/components/shared/BudgetDonut.es.js +25 -0
  29. package/dist/budgets/components/shared/BudgetDonut.es.js.map +1 -0
  30. package/dist/budgets/components/shared/SubBudgetCategory.d.ts +7 -0
  31. package/dist/budgets/components/shared/SubBudgetCategory.es.js +45 -0
  32. package/dist/budgets/components/shared/SubBudgetCategory.es.js.map +1 -0
  33. package/dist/core/constants/repeatingTransactions.d.ts +6 -0
  34. package/dist/core/constants/repeatingTransactions.es.js +18 -3
  35. package/dist/core/constants/repeatingTransactions.es.js.map +1 -1
  36. package/dist/core/stores/BudgetsStore.d.ts +13 -4
  37. package/dist/core/stores/BudgetsStore.es.js +40 -38
  38. package/dist/core/stores/BudgetsStore.es.js.map +1 -1
  39. package/dist/core/types/RepeatingTransaction.d.ts +2 -0
  40. package/dist/core/types/RepeatingTransaction.es.js.map +1 -1
  41. package/dist/core/types/Transaction.d.ts +1 -0
  42. package/dist/core/types/Transaction.es.js.map +1 -1
  43. package/dist/core/types/localization/BudgetsCopy.d.ts +3 -0
  44. package/dist/core/utils/BudgetUtil.d.ts +1 -0
  45. package/dist/core/utils/BudgetUtil.es.js +55 -51
  46. package/dist/core/utils/BudgetUtil.es.js.map +1 -1
  47. package/dist/core/utils/RecurringTransactionsUtil.d.ts +1 -0
  48. package/dist/core/utils/RecurringTransactionsUtil.es.js +145 -143
  49. package/dist/core/utils/RecurringTransactionsUtil.es.js.map +1 -1
  50. package/dist/core/utils/TransactionUtils.d.ts +1 -0
  51. package/dist/recurringtransactions/components/shared/recurringsettings/AddRecurringTransaction.es.js +16 -14
  52. package/dist/recurringtransactions/components/shared/recurringsettings/AddRecurringTransaction.es.js.map +1 -1
  53. package/dist/recurringtransactions/components/shared/recurringsettings/SelectTransaction.es.js +19 -17
  54. package/dist/recurringtransactions/components/shared/recurringsettings/SelectTransaction.es.js.map +1 -1
  55. package/dist/transactions/components/shared/TransactionList.es.js +16 -12
  56. package/dist/transactions/components/shared/TransactionList.es.js.map +1 -1
  57. package/dist/transactions/components/shared/transactiondetails/actions/AddMerchantBudgetAction.es.js +85 -82
  58. package/dist/transactions/components/shared/transactiondetails/actions/AddMerchantBudgetAction.es.js.map +1 -1
  59. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## [9.4.3] - 08-26-2026
2
+
3
+ - **ADDED** - Pass category_guid and main_class_guid when creating repeating transactions (MEW-4051)
4
+ - **ADDED** - Filter selectable transactions for recurring creation to merchant-backed transactions or eligible merchantless bills and income (MEW-4051)
5
+
6
+ ## [9.4.2] - 08-26-2026
7
+ - **ADDED** - Sub budget totals now roll up to parent budget total
8
+ - **ADDED** - Destructive cascade delete of sub-budgets when a parent budget is deleted
9
+ - **REMOVED** - Un-budgeted projected income line
10
+ - **CHANGED** - Colors from `primary.light` to `primary.main`
11
+
1
12
  ## [9.4.1] - 08-26-2026
2
13
 
3
14
  - **REMOVED** - Merchant Guid filter when adding recurring transactions
@@ -2,41 +2,41 @@ import { useAccountStore as K, useBudgetsStore as V, useCategoryStore as P, useE
2
2
  import { useScreenSize as Q } from "../common/hooks/useScreenSize.es.js";
3
3
  import { useWidgetLoadTimer as X } from "../common/hooks/useWidgetLoadTimer.es.js";
4
4
  import $ from "../common/components/drawer/Drawer.es.js";
5
- import { ANALYTICS_EVENTS as u } from "../common/constants/Analytics.es.js";
5
+ import { ANALYTICS_EVENTS as g } from "../common/constants/Analytics.es.js";
6
6
  import ee from "../common/components/Loader.es.js";
7
7
  import { WidgetContainer as te } from "../common/components/WidgetContainer.es.js";
8
8
  import { AddBudgets as oe } from "./components/AddBudgets.es.js";
9
9
  import { BubbleBudgets as re } from "./components/BubbleBudgets.es.js";
10
10
  import { BudgetDetailsDrawer as ie } from "./components/BudgetDetailsDrawer.es.js";
11
- import { BudgetList as ae } from "./components/BudgetList.es.js";
12
- import { Overview as se } from "./components/Overview.es.js";
11
+ import { BudgetList as se } from "./components/BudgetList.es.js";
12
+ import { Overview as ae } from "./components/Overview.es.js";
13
13
  import i from "react";
14
14
  import { observer as ne } from "mobx-react-lite";
15
15
  import f from "@mui/material/Stack";
16
16
  import { endOfMonth as S } from "date-fns/endOfMonth";
17
- import { startOfMonth as g } from "date-fns/startOfMonth";
18
- import { startOfToday as a } from "date-fns/startOfToday";
19
- import { jsx as e, jsxs as h } from "react/jsx-runtime";
17
+ import { startOfMonth as h } from "date-fns/startOfMonth";
18
+ import { startOfToday as s } from "date-fns/startOfToday";
19
+ import { jsx as e, jsxs as p } from "react/jsx-runtime";
20
20
  import { useTheme as le } from "@mui/material/styles";
21
21
  import { isAfter as de } from "date-fns/isAfter";
22
22
  import ce from "@mui/material/Alert";
23
23
  import me from "@mui/material/Snackbar";
24
24
  var A = 480, We = ne(({ onBackClick: T, onMenuClick: v, sx: y }) => {
25
- const E = le(), { onEvent: s } = Y(), { visibleAccounts: _ } = K(), { budgets: n, common: w } = Z(), { isInitialized: l, selectedAccounts: d, setDisplayedDate: L } = q(), { alert: p, dateRange: t, isDataLoaded: c, loadBudgetData: R, setDateRange: m, setAlert: D, setTheme: I, detailedBudgets: b } = V(), { setDateRange: O } = J(), { loadDateRangeCategoryTotals: k, loadMonthlyCategoryTotals: x } = P(), { isSmallTablet: W, isMobile: G, isSmallMobile: M } = Q(), o = W || G || M, [N, r] = i.useState(!1);
25
+ const E = le(), { onEvent: a } = Y(), { visibleAccounts: _ } = K(), { budgets: n, common: w } = Z(), { isInitialized: l, selectedAccounts: d, setDisplayedDate: L } = q(), { alert: c, dateRange: t, isDataLoaded: m, loadBudgetData: R, setDateRange: u, setAlert: D, setTheme: I, detailedBudgets: b } = V(), { setDateRange: O } = J(), { loadDateRangeCategoryTotals: k, loadMonthlyCategoryTotals: x } = P(), { isSmallTablet: W, isMobile: G, isSmallMobile: M } = Q(), o = W || G || M, [N, r] = i.useState(!1);
26
26
  X({
27
27
  widgetName: "BubbleBudgetsWidget",
28
- isLoaded: c
28
+ isLoaded: m
29
29
  }), i.useEffect(() => {
30
- I(E), c || R().finally(() => {
31
- s(u.BUDGETS_VIEW);
30
+ I(E), m || R().finally(() => {
31
+ a(g.BUDGETS_VIEW);
32
32
  });
33
- }, []), i.useEffect(() => (m({
34
- start: g(a()),
35
- end: S(a())
33
+ }, []), i.useEffect(() => (u({
34
+ start: h(s()),
35
+ end: S(s())
36
36
  }), () => {
37
- m({
38
- start: g(a()),
39
- end: S(a())
37
+ u({
38
+ start: h(s()),
39
+ end: S(s())
40
40
  });
41
41
  }), [_]), i.useEffect(() => {
42
42
  l && (L(t.start, t.end), k(d, t.start, t.end).finally(), x(d).finally(), O(t));
@@ -46,20 +46,20 @@ var A = 480, We = ne(({ onBackClick: T, onMenuClick: v, sx: y }) => {
46
46
  t
47
47
  ]);
48
48
  const U = (B) => {
49
- m({
49
+ u({
50
50
  start: B[0] || /* @__PURE__ */ new Date(),
51
51
  end: B[1] || /* @__PURE__ */ new Date()
52
52
  });
53
53
  }, j = () => {
54
- s(u.BUDGETS_CLICK_FILTER);
54
+ a(g.BUDGETS_CLICK_FILTER);
55
55
  }, C = () => {
56
- r(!0), s(u.BUDGETS_CLICK_ADD);
56
+ r(!0), a(g.BUDGETS_CLICK_ADD);
57
57
  }, z = () => {
58
58
  r(!1);
59
59
  }, F = () => {
60
60
  r(!1);
61
- }, H = de(t.end, g(/* @__PURE__ */ new Date()));
62
- return !l || !c ? /* @__PURE__ */ e(ee, {}) : /* @__PURE__ */ h(te, {
61
+ }, H = de(t.end, h(/* @__PURE__ */ new Date()));
62
+ return !l || !m ? /* @__PURE__ */ e(ee, {}) : /* @__PURE__ */ p(te, {
63
63
  actions: [{
64
64
  iconName: "add",
65
65
  label: n.add_title,
@@ -77,7 +77,7 @@ var A = 480, We = ne(({ onBackClick: T, onMenuClick: v, sx: y }) => {
77
77
  sx: y,
78
78
  title: n.budgets_title,
79
79
  children: [
80
- /* @__PURE__ */ h(f, {
80
+ /* @__PURE__ */ p(f, {
81
81
  direction: o ? "column" : "row",
82
82
  height: "100%",
83
83
  sx: { justifyContent: "center" },
@@ -91,7 +91,7 @@ var A = 480, We = ne(({ onBackClick: T, onMenuClick: v, sx: y }) => {
91
91
  shouldShowZeroState: b.length === 0,
92
92
  unavailableWidth: o ? 0 : A
93
93
  })
94
- }), b.length !== 0 && /* @__PURE__ */ h(f, {
94
+ }), b.length !== 0 && /* @__PURE__ */ p(f, {
95
95
  gap: 24,
96
96
  height: "100%",
97
97
  sx: {
@@ -99,7 +99,7 @@ var A = 480, We = ne(({ onBackClick: T, onMenuClick: v, sx: y }) => {
99
99
  mt: 48
100
100
  },
101
101
  width: o ? "100%" : A,
102
- children: [/* @__PURE__ */ e(se, {}), /* @__PURE__ */ e(ae, {})]
102
+ children: [/* @__PURE__ */ e(ae, {}), /* @__PURE__ */ e(se, {})]
103
103
  })]
104
104
  }),
105
105
  /* @__PURE__ */ e(ie, {}),
@@ -120,17 +120,17 @@ var A = 480, We = ne(({ onBackClick: T, onMenuClick: v, sx: y }) => {
120
120
  },
121
121
  autoHideDuration: 3500,
122
122
  onClose: () => {
123
- D("");
123
+ D(null);
124
124
  },
125
- open: !!p,
125
+ open: !!c,
126
126
  children: /* @__PURE__ */ e(ce, {
127
127
  closeText: "",
128
128
  onClose: () => {
129
- D("");
129
+ D(null);
130
130
  },
131
- severity: "success",
131
+ severity: c?.severity ?? "success",
132
132
  variant: "filled",
133
- children: p
133
+ children: c?.msg
134
134
  })
135
135
  })
136
136
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"BubbleBudgetsWidget.es.js","names":[],"sources":["../../src/budgets/BubbleBudgetsWidget.tsx"],"sourcesContent":["import React from 'react'\nimport { observer } from 'mobx-react-lite'\n\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { isAfter } from 'date-fns/isAfter'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\n\nimport Alert from '@mui/material/Alert'\nimport Snackbar from '@mui/material/Snackbar'\nimport Stack from '@mui/material/Stack'\nimport { useTheme } from '@mui/material/styles'\nimport { DateRange } from '@mui/x-date-pickers-pro'\n\nimport {\n ANALYTICS_EVENTS,\n Drawer,\n Loader,\n useAccountStore,\n useBudgetsStore,\n useCategoryStore,\n useEvent,\n useGlobalCopyStore,\n useGlobalUiStore,\n useRecurringTransactionsStore,\n useScreenSize,\n useWidgetLoadTimer,\n WidgetContainer,\n} from '../common'\nimport { WidgetProps } from '../core'\n\nimport { AddBudgets } from './components/AddBudgets'\nimport { BubbleBudgets } from './components/BubbleBudgets'\nimport { BudgetDetailsDrawer } from './components/BudgetDetailsDrawer'\nimport { BudgetList } from './components/BudgetList'\nimport { Overview } from './components/Overview'\n\nconst BUDGET_LIST_WIDTH = 480\n\nexport const BubbleBudgetsWidget: React.FC<WidgetProps> = observer(\n ({ onBackClick, onMenuClick, sx }) => {\n const theme = useTheme()\n const { onEvent } = useEvent()\n const { visibleAccounts: accounts } = useAccountStore()\n const { budgets: copy, common: commonCopy } = useGlobalCopyStore()\n const { isInitialized, selectedAccounts, setDisplayedDate } = useGlobalUiStore()\n const {\n alert,\n dateRange,\n isDataLoaded,\n loadBudgetData,\n setDateRange,\n setAlert,\n setTheme,\n detailedBudgets: budgets,\n } = useBudgetsStore()\n const { setDateRange: setRecurringDateRange } = useRecurringTransactionsStore()\n const { loadDateRangeCategoryTotals, loadMonthlyCategoryTotals } = useCategoryStore()\n const { isSmallTablet, isMobile, isSmallMobile } = useScreenSize()\n const isColumnWidths = isSmallTablet || isMobile || isSmallMobile\n\n const [isAddOpen, setIsAddOpen] = React.useState(false)\n\n useWidgetLoadTimer({\n widgetName: 'BubbleBudgetsWidget',\n isLoaded: isDataLoaded,\n })\n\n React.useEffect(() => {\n setTheme(theme)\n if (!isDataLoaded) {\n loadBudgetData().finally(() => {\n onEvent(ANALYTICS_EVENTS.BUDGETS_VIEW)\n })\n }\n }, [])\n\n React.useEffect(() => {\n setDateRange({ start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) })\n\n return () => {\n setDateRange({ start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) })\n }\n }, [accounts])\n\n React.useEffect(() => {\n if (isInitialized) {\n setDisplayedDate(dateRange.start, dateRange.end)\n loadDateRangeCategoryTotals(selectedAccounts, dateRange.start, dateRange.end).finally()\n loadMonthlyCategoryTotals(selectedAccounts).finally()\n setRecurringDateRange(dateRange)\n }\n }, [isInitialized, selectedAccounts, dateRange])\n\n const onMonthChanged = (dateRange: DateRange<Date>) => {\n setDateRange({ start: dateRange[0] || new Date(), end: dateRange[1] || new Date() })\n }\n\n const handleAccountFilterClick = () => {\n onEvent(ANALYTICS_EVENTS.BUDGETS_CLICK_FILTER)\n }\n\n const handleAddClick = () => {\n setIsAddOpen(true)\n onEvent(ANALYTICS_EVENTS.BUDGETS_CLICK_ADD)\n }\n\n const handleBudgetAdded = () => {\n setIsAddOpen(false)\n }\n\n const handleBudgetsRecalculated = () => {\n setIsAddOpen(false)\n }\n\n const shouldDisableNext = isAfter(dateRange.end, startOfMonth(new Date()))\n\n if (!isInitialized || !isDataLoaded) return <Loader />\n\n return (\n <WidgetContainer\n actions={[\n {\n iconName: 'add',\n label: copy.add_title,\n onClick: handleAddClick,\n },\n ]}\n calendarActions={{\n onRangeChanged: onMonthChanged,\n shouldDisableNext,\n shouldDisablePicker: true,\n }}\n hasDivider={true}\n onAccountsFilterClick={handleAccountFilterClick}\n onBackClick={onBackClick}\n onMenuClick={onMenuClick}\n sx={sx}\n title={copy.budgets_title}\n >\n <Stack\n direction={!isColumnWidths ? 'row' : 'column'}\n height=\"100%\"\n sx={{ justifyContent: 'center' }}\n width=\"100%\"\n >\n <Stack height={!isColumnWidths ? 'calc(100dvh - 150px)' : 450}>\n <BubbleBudgets\n createBudgetOnClick={handleAddClick}\n height={!isColumnWidths ? 800 : 450}\n isDraggable={true}\n shouldShowZeroState={budgets.length === 0}\n unavailableWidth={!isColumnWidths ? BUDGET_LIST_WIDTH : 0}\n />\n </Stack>\n {budgets.length !== 0 && (\n <Stack\n gap={24}\n height=\"100%\"\n sx={{ mr: 24, mt: 48 }}\n width={!isColumnWidths ? BUDGET_LIST_WIDTH : '100%'}\n >\n <Overview />\n <BudgetList />\n </Stack>\n )}\n </Stack>\n\n <BudgetDetailsDrawer />\n\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isAddOpen}\n onClose={() => setIsAddOpen(false)}\n title={copy.add_new_title}\n >\n <AddBudgets\n onAddBudget={handleBudgetAdded}\n onRecalculateBudgets={handleBudgetsRecalculated}\n />\n </Drawer>\n\n <Snackbar\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n autoHideDuration={3500}\n onClose={() => {\n setAlert('')\n }}\n open={Boolean(alert)}\n >\n <Alert\n closeText=\"\"\n onClose={() => {\n setAlert('')\n }}\n severity={'success'}\n variant=\"filled\"\n >\n {alert}\n </Alert>\n </Snackbar>\n </WidgetContainer>\n )\n },\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAqCA,IAAM,IAAoB,KAEb,KAA6C,GAAA,CACvD,EAAE,aAAA,GAAa,aAAA,GAAa,IAAA,EAAA,MAAS;AACpC,QAAM,IAAQ,GAAS,GACjB,EAAE,SAAA,EAAA,IAAY,EAAS,GACvB,EAAE,iBAAiB,EAAA,IAAa,EAAgB,GAChD,EAAE,SAAS,GAAM,QAAQ,EAAA,IAAe,EAAmB,GAC3D,EAAE,eAAA,GAAe,kBAAA,GAAkB,kBAAA,EAAA,IAAqB,EAAiB,GACzE,EACJ,OAAA,GACA,WAAA,GACA,cAAA,GACA,gBAAA,GACA,cAAA,GACA,UAAA,GACA,UAAA,GACA,iBAAiB,EAAA,IACf,EAAgB,GACd,EAAE,cAAc,EAAA,IAA0B,EAA8B,GACxE,EAAE,6BAAA,GAA6B,2BAAA,EAAA,IAA8B,EAAiB,GAC9E,EAAE,eAAA,GAAe,UAAA,GAAU,eAAA,EAAA,IAAkB,EAAc,GAC3D,IAAiB,KAAiB,KAAY,GAE9C,CAAC,GAAW,CAAA,IAAgB,EAAM,SAAS,EAAK;AAEtD,EAAA,EAAmB;AAAA,IACjB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ,CAAC,GAED,EAAM,UAAA,MAAgB;AACpB,IAAA,EAAS,CAAK,GACT,KACH,EAAe,EAAE,QAAA,MAAc;AAC7B,MAAA,EAAQ,EAAiB,YAAY;AAAA,IACvC,CAAC;AAAA,EAEL,GAAG,CAAC,CAAC,GAEL,EAAM,UAAA,OACJ,EAAa;AAAA,IAAE,OAAO,EAAa,EAAa,CAAC;AAAA,IAAG,KAAK,EAAW,EAAa,CAAC;AAAA,EAAE,CAAC,GAErF,MAAa;AACX,IAAA,EAAa;AAAA,MAAE,OAAO,EAAa,EAAa,CAAC;AAAA,MAAG,KAAK,EAAW,EAAa,CAAC;AAAA,IAAE,CAAC;AAAA,EACvF,IACC,CAAC,CAAQ,CAAC,GAEb,EAAM,UAAA,MAAgB;AACpB,IAAI,MACF,EAAiB,EAAU,OAAO,EAAU,GAAG,GAC/C,EAA4B,GAAkB,EAAU,OAAO,EAAU,GAAG,EAAE,QAAQ,GACtF,EAA0B,CAAgB,EAAE,QAAQ,GACpD,EAAsB,CAAS;AAAA,EAEnC,GAAG;AAAA,IAAC;AAAA,IAAe;AAAA,IAAkB;AAAA,EAAS,CAAC;AAE/C,QAAM,IAAA,CAAkB,MAA+B;AACrD,IAAA,EAAa;AAAA,MAAE,OAAO,EAAU,CAAA,KAAM,oBAAI,KAAK;AAAA,MAAG,KAAK,EAAU,CAAA,KAAM,oBAAI,KAAK;AAAA,IAAE,CAAC;AAAA,EACrF,GAEM,IAAA,MAAiC;AACrC,IAAA,EAAQ,EAAiB,oBAAoB;AAAA,EAC/C,GAEM,IAAA,MAAuB;AAC3B,IAAA,EAAa,EAAI,GACjB,EAAQ,EAAiB,iBAAiB;AAAA,EAC5C,GAEM,IAAA,MAA0B;AAC9B,IAAA,EAAa,EAAK;AAAA,EACpB,GAEM,IAAA,MAAkC;AACtC,IAAA,EAAa,EAAK;AAAA,EACpB,GAEM,IAAoB,GAAQ,EAAU,KAAK,EAAa,oBAAI,KAAK,CAAC,CAAC;AAEzE,SAAI,CAAC,KAAiB,CAAC,IAAqB,gBAAA,EAAC,IAAD,CAAS,CAAA,IAGnD,gBAAA,EAAC,IAAD;AAAA,IACE,SAAS,CACP;AAAA,MACE,UAAU;AAAA,MACV,OAAO,EAAK;AAAA,MACZ,SAAS;AAAA,IACX,CACF;AAAA,IACA,iBAAiB;AAAA,MACf,gBAAgB;AAAA,MAChB,mBAAA;AAAA,MACA,qBAAqB;AAAA,IACvB;AAAA,IACA,YAAY;AAAA,IACZ,uBAAuB;AAAA,IACV,aAAA;AAAA,IACA,aAAA;AAAA,IACT,IAAA;AAAA,IACJ,OAAO,EAAK;AAAA,IAlBd,UAAA;AAAA,MAoBE,gBAAA,EAAC,GAAD;AAAA,QACE,WAAY,IAAyB,WAAR;AAAA,QAC7B,QAAO;AAAA,QACP,IAAI,EAAE,gBAAgB,SAAS;AAAA,QAC/B,OAAM;AAAA,QAJR,UAAA,CAME,gBAAA,EAAC,GAAD;AAAA,UAAO,QAAS,IAA0C,MAAzB;AAAA,UAC/B,UAAA,gBAAA,EAAC,IAAD;AAAA,YACE,qBAAqB;AAAA,YACrB,QAAS,IAAuB,MAAN;AAAA,YAC1B,aAAa;AAAA,YACb,qBAAqB,EAAQ,WAAW;AAAA,YACxC,kBAAmB,IAAqC,IAApB;AAAA,UACrC,CAAA;AAAA,QACI,CAAA,GACN,EAAQ,WAAW,KAClB,gBAAA,EAAC,GAAD;AAAA,UACE,KAAK;AAAA,UACL,QAAO;AAAA,UACP,IAAI;AAAA,YAAE,IAAI;AAAA,YAAI,IAAI;AAAA,UAAG;AAAA,UACrB,OAAQ,IAAqC,SAApB;AAAA,UAJ3B,UAAA,CAME,gBAAA,EAAC,IAAD,CAAW,CAAA,GACX,gBAAA,EAAC,IAAD,CAAa,CAAA,CACR;AAAA,QAEJ,CAAA,CAAA;AAAA;MAEP,gBAAA,EAAC,IAAD,CAAsB,CAAA;AAAA,MAEtB,gBAAA,EAAC,GAAD;AAAA,QACE,gBAAgB,EAAW;AAAA,QAC3B,QAAQ;AAAA,QACR,SAAA,MAAe,EAAa,EAAK;AAAA,QACjC,OAAO,EAAK;AAAA,QAEZ,UAAA,gBAAA,EAAC,IAAD;AAAA,UACE,aAAa;AAAA,UACb,sBAAsB;AAAA,QACvB,CAAA;AAAA,MACK,CAAA;AAAA,MAER,gBAAA,EAAC,IAAD;AAAA,QACE,cAAc;AAAA,UAAE,UAAU;AAAA,UAAU,YAAY;AAAA,QAAQ;AAAA,QACxD,kBAAkB;AAAA,QAClB,SAAA,MAAe;AACb,UAAA,EAAS,EAAE;AAAA,QACb;AAAA,QACA,MAAM,EAAQ;AAAA,QAEd,UAAA,gBAAA,EAAC,IAAD;AAAA,UACE,WAAU;AAAA,UACV,SAAA,MAAe;AACb,YAAA,EAAS,EAAE;AAAA,UACb;AAAA,UACA,UAAU;AAAA,UACV,SAAQ;AAAA,UAEP,UAAA;AAAA,QACI,CAAA;AAAA,MACC,CAAA;AAAA,IACK;AAAA;AAErB,CACF"}
1
+ {"version":3,"file":"BubbleBudgetsWidget.es.js","names":[],"sources":["../../src/budgets/BubbleBudgetsWidget.tsx"],"sourcesContent":["import React from 'react'\nimport { observer } from 'mobx-react-lite'\n\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { isAfter } from 'date-fns/isAfter'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\n\nimport Alert from '@mui/material/Alert'\nimport Snackbar from '@mui/material/Snackbar'\nimport Stack from '@mui/material/Stack'\nimport { useTheme } from '@mui/material/styles'\nimport { DateRange } from '@mui/x-date-pickers-pro'\n\nimport {\n ANALYTICS_EVENTS,\n Drawer,\n Loader,\n useAccountStore,\n useBudgetsStore,\n useCategoryStore,\n useEvent,\n useGlobalCopyStore,\n useGlobalUiStore,\n useRecurringTransactionsStore,\n useScreenSize,\n useWidgetLoadTimer,\n WidgetContainer,\n} from '../common'\nimport { WidgetProps } from '../core'\n\nimport { AddBudgets } from './components/AddBudgets'\nimport { BubbleBudgets } from './components/BubbleBudgets'\nimport { BudgetDetailsDrawer } from './components/BudgetDetailsDrawer'\nimport { BudgetList } from './components/BudgetList'\nimport { Overview } from './components/Overview'\n\nconst BUDGET_LIST_WIDTH = 480\n\nexport const BubbleBudgetsWidget: React.FC<WidgetProps> = observer(\n ({ onBackClick, onMenuClick, sx }) => {\n const theme = useTheme()\n const { onEvent } = useEvent()\n const { visibleAccounts: accounts } = useAccountStore()\n const { budgets: copy, common: commonCopy } = useGlobalCopyStore()\n const { isInitialized, selectedAccounts, setDisplayedDate } = useGlobalUiStore()\n const {\n alert,\n dateRange,\n isDataLoaded,\n loadBudgetData,\n setDateRange,\n setAlert,\n setTheme,\n detailedBudgets: budgets,\n } = useBudgetsStore()\n const { setDateRange: setRecurringDateRange } = useRecurringTransactionsStore()\n const { loadDateRangeCategoryTotals, loadMonthlyCategoryTotals } = useCategoryStore()\n const { isSmallTablet, isMobile, isSmallMobile } = useScreenSize()\n const isColumnWidths = isSmallTablet || isMobile || isSmallMobile\n\n const [isAddOpen, setIsAddOpen] = React.useState(false)\n\n useWidgetLoadTimer({\n widgetName: 'BubbleBudgetsWidget',\n isLoaded: isDataLoaded,\n })\n\n React.useEffect(() => {\n setTheme(theme)\n if (!isDataLoaded) {\n loadBudgetData().finally(() => {\n onEvent(ANALYTICS_EVENTS.BUDGETS_VIEW)\n })\n }\n }, [])\n\n React.useEffect(() => {\n setDateRange({ start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) })\n\n return () => {\n setDateRange({ start: startOfMonth(startOfToday()), end: endOfMonth(startOfToday()) })\n }\n }, [accounts])\n\n React.useEffect(() => {\n if (isInitialized) {\n setDisplayedDate(dateRange.start, dateRange.end)\n loadDateRangeCategoryTotals(selectedAccounts, dateRange.start, dateRange.end).finally()\n loadMonthlyCategoryTotals(selectedAccounts).finally()\n setRecurringDateRange(dateRange)\n }\n }, [isInitialized, selectedAccounts, dateRange])\n\n const onMonthChanged = (dateRange: DateRange<Date>) => {\n setDateRange({ start: dateRange[0] || new Date(), end: dateRange[1] || new Date() })\n }\n\n const handleAccountFilterClick = () => {\n onEvent(ANALYTICS_EVENTS.BUDGETS_CLICK_FILTER)\n }\n\n const handleAddClick = () => {\n setIsAddOpen(true)\n onEvent(ANALYTICS_EVENTS.BUDGETS_CLICK_ADD)\n }\n\n const handleBudgetAdded = () => {\n setIsAddOpen(false)\n }\n\n const handleBudgetsRecalculated = () => {\n setIsAddOpen(false)\n }\n\n const shouldDisableNext = isAfter(dateRange.end, startOfMonth(new Date()))\n\n if (!isInitialized || !isDataLoaded) return <Loader />\n\n return (\n <WidgetContainer\n actions={[\n {\n iconName: 'add',\n label: copy.add_title,\n onClick: handleAddClick,\n },\n ]}\n calendarActions={{\n onRangeChanged: onMonthChanged,\n shouldDisableNext,\n shouldDisablePicker: true,\n }}\n hasDivider={true}\n onAccountsFilterClick={handleAccountFilterClick}\n onBackClick={onBackClick}\n onMenuClick={onMenuClick}\n sx={sx}\n title={copy.budgets_title}\n >\n <Stack\n direction={!isColumnWidths ? 'row' : 'column'}\n height=\"100%\"\n sx={{ justifyContent: 'center' }}\n width=\"100%\"\n >\n <Stack height={!isColumnWidths ? 'calc(100dvh - 150px)' : 450}>\n <BubbleBudgets\n createBudgetOnClick={handleAddClick}\n height={!isColumnWidths ? 800 : 450}\n isDraggable={true}\n shouldShowZeroState={budgets.length === 0}\n unavailableWidth={!isColumnWidths ? BUDGET_LIST_WIDTH : 0}\n />\n </Stack>\n {budgets.length !== 0 && (\n <Stack\n gap={24}\n height=\"100%\"\n sx={{ mr: 24, mt: 48 }}\n width={!isColumnWidths ? BUDGET_LIST_WIDTH : '100%'}\n >\n <Overview />\n <BudgetList />\n </Stack>\n )}\n </Stack>\n\n <BudgetDetailsDrawer />\n\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isAddOpen}\n onClose={() => setIsAddOpen(false)}\n title={copy.add_new_title}\n >\n <AddBudgets\n onAddBudget={handleBudgetAdded}\n onRecalculateBudgets={handleBudgetsRecalculated}\n />\n </Drawer>\n\n <Snackbar\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n autoHideDuration={3500}\n onClose={() => {\n setAlert(null)\n }}\n open={Boolean(alert)}\n >\n <Alert\n closeText=\"\"\n onClose={() => {\n setAlert(null)\n }}\n severity={alert?.severity ?? 'success'}\n variant=\"filled\"\n >\n {alert?.msg}\n </Alert>\n </Snackbar>\n </WidgetContainer>\n )\n },\n)\n"],"mappings":"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"}
@@ -1,27 +1,30 @@
1
- import { buildDynamicCopy as s } from "../../core/utils/Localization.es.js";
1
+ import { buildDynamicCopy as p } from "../../core/utils/Localization.es.js";
2
2
  import { useBudgetsStore as n, useGlobalCopyStore as c } from "../../common/context/hooks.es.js";
3
3
  import { Header as g } from "./addbudget/Header.es.js";
4
4
  import { RecalculateBudgets as l } from "./addbudget/RecalculateBudgets.es.js";
5
5
  import { UnbudgetedRow as f } from "./addbudget/UnbudgetedRow.es.js";
6
6
  import { observer as b } from "mobx-react-lite";
7
7
  import B from "@mui/material/Stack";
8
- import { jsx as o, jsxs as h } from "react/jsx-runtime";
8
+ import { jsx as r, jsxs as h } from "react/jsx-runtime";
9
9
  import x from "@mui/material/Box";
10
- import A from "@mui/material/List";
11
- var G = b(({ onAddBudget: e, onRecalculateBudgets: t }) => {
12
- const { budgets: d } = c(), { addBudget: m, setAlert: i, unbudgetedCategories: u } = n(), a = async (r, p) => {
13
- await m(r, p), e?.(), i(s(d.alert_budget_created, r.name));
10
+ import y from "@mui/material/List";
11
+ var G = b(({ onAddBudget: o, onRecalculateBudgets: t }) => {
12
+ const { budgets: d } = c(), { addBudget: m, setAlert: s, unbudgetedCategories: i } = n(), u = async (e, a) => {
13
+ await m(e, a), o?.(), s({
14
+ msg: p(d.alert_budget_created, e.name),
15
+ severity: "success"
16
+ });
14
17
  };
15
18
  return /* @__PURE__ */ h(B, { children: [
16
- /* @__PURE__ */ o(g, {}),
17
- /* @__PURE__ */ o(x, {
19
+ /* @__PURE__ */ r(g, {}),
20
+ /* @__PURE__ */ r(x, {
18
21
  bgcolor: "background.paper",
19
- children: /* @__PURE__ */ o(A, { children: u.map((r) => /* @__PURE__ */ o(f, {
20
- category: r,
21
- onAddBudget: a
22
- }, r.guid)) })
22
+ children: /* @__PURE__ */ r(y, { children: i.map((e) => /* @__PURE__ */ r(f, {
23
+ category: e,
24
+ onAddBudget: u
25
+ }, e.guid)) })
23
26
  }),
24
- /* @__PURE__ */ o(l, { onRecalculateBudgets: t })
27
+ /* @__PURE__ */ r(l, { onRecalculateBudgets: t })
25
28
  ] });
26
29
  });
27
30
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"AddBudgets.es.js","names":[],"sources":["../../../src/budgets/components/AddBudgets.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport Box from '@mui/material/Box'\nimport List from '@mui/material/List'\nimport Stack from '@mui/material/Stack'\n\nimport { useBudgetsStore, useGlobalCopyStore } from '../../common'\nimport { type DetailedCategory } from '../../core'\n\nimport { Header } from './addbudget/Header'\nimport { RecalculateBudgets } from './addbudget/RecalculateBudgets'\nimport { UnbudgetedRow } from './addbudget/UnbudgetedRow'\nimport { buildDynamicCopy } from '../../core/utils/Localization'\n\ninterface AddBudgetsProps {\n onAddBudget?: () => void\n onRecalculateBudgets?: () => void\n}\n\nexport const AddBudgets = observer(({ onAddBudget, onRecalculateBudgets }: AddBudgetsProps) => {\n const { budgets: copy } = useGlobalCopyStore()\n const { addBudget, setAlert, unbudgetedCategories } = useBudgetsStore()\n\n const handleOnAddBudget = async (category: DetailedCategory, amount: number) => {\n await addBudget(category, amount)\n onAddBudget?.()\n setAlert(buildDynamicCopy(copy.alert_budget_created, category.name) as string)\n }\n\n return (\n <Stack>\n <Header />\n\n <Box bgcolor=\"background.paper\">\n <List>\n {unbudgetedCategories.map((category) => (\n <UnbudgetedRow\n category={category}\n key={category.guid}\n onAddBudget={handleOnAddBudget}\n />\n ))}\n </List>\n </Box>\n\n <RecalculateBudgets onRecalculateBudgets={onRecalculateBudgets} />\n </Stack>\n )\n})\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,IAAa,EAAA,CAAU,EAAE,aAAA,GAAa,sBAAA,EAAA,MAA4C;AAC7F,QAAM,EAAE,SAAS,EAAA,IAAS,EAAmB,GACvC,EAAE,WAAA,GAAW,UAAA,GAAU,sBAAA,EAAA,IAAyB,EAAgB,GAEhE,IAAoB,OAAO,GAA4B,MAAmB;AAC9E,UAAM,EAAU,GAAU,CAAM,GAChC,IAAc,GACd,EAAS,EAAiB,EAAK,sBAAsB,EAAS,IAAI,CAAW;AAAA,EAC/E;AAEA,SACE,gBAAA,EAAC,GAAD,EAAA,UAAA;AAAA,IACE,gBAAA,EAAC,GAAD,CAAS,CAAA;AAAA,IAET,gBAAA,EAAC,GAAD;AAAA,MAAK,SAAQ;AAAA,MACX,UAAA,gBAAA,EAAC,GAAD,EAAA,UACG,EAAqB,IAAA,CAAK,MACzB,gBAAA,EAAC,GAAD;AAAA,QACY,UAAA;AAAA,QAEV,aAAa;AAAA,MACd,GAFM,EAAS,IAEf,CACF,EACG,CAAA;AAAA,IACH,CAAA;AAAA,IAEL,gBAAA,EAAC,GAAD,EAA0C,sBAAA,EAAuB,CAAA;AAAA,EAC5D,EAAA,CAAA;AAEX,CAAC"}
1
+ {"version":3,"file":"AddBudgets.es.js","names":[],"sources":["../../../src/budgets/components/AddBudgets.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport Box from '@mui/material/Box'\nimport List from '@mui/material/List'\nimport Stack from '@mui/material/Stack'\n\nimport { useBudgetsStore, useGlobalCopyStore } from '../../common'\nimport { type DetailedCategory } from '../../core'\n\nimport { Header } from './addbudget/Header'\nimport { RecalculateBudgets } from './addbudget/RecalculateBudgets'\nimport { UnbudgetedRow } from './addbudget/UnbudgetedRow'\nimport { buildDynamicCopy } from '../../core/utils/Localization'\n\ninterface AddBudgetsProps {\n onAddBudget?: () => void\n onRecalculateBudgets?: () => void\n}\n\nexport const AddBudgets = observer(({ onAddBudget, onRecalculateBudgets }: AddBudgetsProps) => {\n const { budgets: copy } = useGlobalCopyStore()\n const { addBudget, setAlert, unbudgetedCategories } = useBudgetsStore()\n\n const handleOnAddBudget = async (category: DetailedCategory, amount: number) => {\n await addBudget(category, amount)\n onAddBudget?.()\n setAlert({\n msg: buildDynamicCopy(copy.alert_budget_created, category.name) as string,\n severity: 'success',\n })\n }\n\n return (\n <Stack>\n <Header />\n\n <Box bgcolor=\"background.paper\">\n <List>\n {unbudgetedCategories.map((category) => (\n <UnbudgetedRow\n category={category}\n key={category.guid}\n onAddBudget={handleOnAddBudget}\n />\n ))}\n </List>\n </Box>\n\n <RecalculateBudgets onRecalculateBudgets={onRecalculateBudgets} />\n </Stack>\n )\n})\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,IAAa,EAAA,CAAU,EAAE,aAAA,GAAa,sBAAA,EAAA,MAA4C;AAC7F,QAAM,EAAE,SAAS,EAAA,IAAS,EAAmB,GACvC,EAAE,WAAA,GAAW,UAAA,GAAU,sBAAA,EAAA,IAAyB,EAAgB,GAEhE,IAAoB,OAAO,GAA4B,MAAmB;AAC9E,UAAM,EAAU,GAAU,CAAM,GAChC,IAAc,GACd,EAAS;AAAA,MACP,KAAK,EAAiB,EAAK,sBAAsB,EAAS,IAAI;AAAA,MAC9D,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SACE,gBAAA,EAAC,GAAD,EAAA,UAAA;AAAA,IACE,gBAAA,EAAC,GAAD,CAAS,CAAA;AAAA,IAET,gBAAA,EAAC,GAAD;AAAA,MAAK,SAAQ;AAAA,MACX,UAAA,gBAAA,EAAC,GAAD,EAAA,UACG,EAAqB,IAAA,CAAK,MACzB,gBAAA,EAAC,GAAD;AAAA,QACY,UAAA;AAAA,QAEV,aAAa;AAAA,MACd,GAFM,EAAS,IAEf,CACF,EACG,CAAA;AAAA,IACH,CAAA;AAAA,IAEL,gBAAA,EAAC,GAAD,EAA0C,sBAAA,EAAuB,CAAA;AAAA,EAC5D,EAAA,CAAA;AAEX,CAAC"}
@@ -1,106 +1,144 @@
1
- import { buildDynamicCopy as c } from "../../core/utils/Localization.es.js";
2
- import { useBudgetsStore as E, useGlobalCopyStore as N, useGlobalUiStore as P, useTransactionStore as G } from "../../common/context/hooks.es.js";
3
- import _ from "../../common/components/dialog/Dialog.es.js";
4
- import I from "../../common/components/drawer/Drawer.es.js";
5
- import { BudgetAmount as $ } from "./shared/BudgetAmount.es.js";
6
- import { BudgetDetails as j } from "./budgetdetails/BudgetDetails.es.js";
1
+ import { buildDynamicCopy as u } from "../../core/utils/Localization.es.js";
2
+ import { useBudgetsStore as F, useGlobalCopyStore as R, useGlobalUiStore as U, useTransactionStore as z } from "../../common/context/hooks.es.js";
3
+ import C from "../../common/components/dialog/Dialog.es.js";
4
+ import H from "../../common/components/drawer/Drawer.es.js";
5
+ import { isInvalidAmount as x } from "../../core/utils/BudgetUtil.es.js";
6
+ import { BudgetAmount as L } from "./shared/BudgetAmount.es.js";
7
+ import { BudgetDetails as M } from "./budgetdetails/BudgetDetails.es.js";
8
+ import { SubBudgetAmounts as q } from "./budgetdetails/SubBudgetAmounts.es.js";
7
9
  import r from "react";
8
- import { observer as F } from "mobx-react-lite";
9
- import { Text as R } from "@mxenabled/mxui";
10
- import { jsx as o, jsxs as f } from "react/jsx-runtime";
11
- import U from "@mui/material/Alert";
12
- import k from "@mui/material/Snackbar";
13
- var Z = F(() => {
14
- const { selectedAccountGuids: b } = P(), { budgets: t, common: n } = N(), { alert: d, dateRange: h, deleteBudget: C, selectedBudget: e, selectedSubBudget: S, setAlert: a, setSelectedBudget: B, updateBudget: A } = E(), { setFilter: D } = G(), [v, u] = r.useState(!1), [x, s] = r.useState(!1), [O, m] = r.useState(!1), [i, l] = r.useState("");
10
+ import { observer as J } from "mobx-react-lite";
11
+ import { Text as K } from "@mxenabled/mxui";
12
+ import { jsx as a, jsxs as B } from "react/jsx-runtime";
13
+ import Q from "@mui/material/Alert";
14
+ import V from "@mui/material/Snackbar";
15
+ var D = (d) => Object.fromEntries((d?.subBudgets ?? []).map((t) => [t.guid, `${t.amount}`])), ce = J(() => {
16
+ const { selectedAccountGuids: d } = U(), { budgets: t, common: m } = R(), { alert: l, dateRange: O, deleteBudget: T, selectedBudget: e, selectedSubBudget: w, setAlert: c, setSelectedBudget: N, updateBudget: h } = F(), { setFilter: E } = z(), [P, S] = r.useState(!1), [$, g] = r.useState(!1), [I, y] = r.useState(!1), [n, p] = r.useState(""), [_, b] = r.useState({});
15
17
  r.useEffect(() => {
16
- e && !S && (l(`${e.amount}`), u(!0), D({
17
- accounts: b,
18
- dateRange: h,
19
- custom: (y) => y.category_guid === e.category_guid || y.top_level_category_guid === e.category_guid,
18
+ e && !w && (p(`${e.amount}`), b(D(e)), S(!0), E({
19
+ accounts: d,
20
+ dateRange: O,
21
+ custom: (o) => o.category_guid === e.category_guid || o.top_level_category_guid === e.category_guid,
20
22
  showSplits: !0
21
23
  }));
22
24
  }, [e]);
23
- const T = async () => {
24
- e && (await A({
25
- ...e,
26
- amount: Number(i),
27
- percentage: e.category.totalAmount / Number(i) * 100
28
- }), s(!1), a(c(t.alert_budget_updated, e.category.name)));
29
- }, w = async () => {
30
- e && (await C(e.guid), a(c(t.alert_budget_deleted, e.category.name))), p();
31
- }, p = () => {
32
- u(!1), setTimeout(() => {
33
- B(void 0);
25
+ const j = async () => {
26
+ if (e) {
27
+ let o = !0;
28
+ e.subBudgets.length > 0 ? o = (await Promise.all(e.subBudgets.map((s) => {
29
+ const i = Number(_[s.guid] ?? s.amount);
30
+ return h({
31
+ ...s,
32
+ amount: i,
33
+ percentage: i ? s.category.currentAmount / i * 100 : 0
34
+ });
35
+ }))).every(Boolean) : o = await h({
36
+ ...e,
37
+ amount: Number(n),
38
+ percentage: Number(n) ? e.category.totalAmount / Number(n) * 100 : 0
39
+ }), c(o ? {
40
+ msg: u(t.alert_budget_updated, e.category.name),
41
+ severity: "success"
42
+ } : {
43
+ msg: u(t.error_alert_edit_merchant_budget, e.category.name),
44
+ severity: "error"
45
+ }), g(!1);
46
+ }
47
+ }, G = async () => {
48
+ if (e) {
49
+ const o = await T(e.guid);
50
+ y(!1), c(o ? {
51
+ msg: u(t.alert_budget_deleted, e.category.name),
52
+ severity: "success"
53
+ } : {
54
+ msg: u(t.error_alert_delete_merchant_budget, e.category.name),
55
+ severity: "error"
56
+ }), o && A();
57
+ }
58
+ }, A = () => {
59
+ S(!1), setTimeout(() => {
60
+ N(void 0);
34
61
  }, 250);
35
- }, g = () => {
36
- s(!1), l(`${e?.amount}`);
62
+ }, v = () => {
63
+ g(!1), p(`${e?.amount}`), b(D(e));
37
64
  };
38
- if (e)
39
- return /* @__PURE__ */ f(r.Fragment, { children: [
40
- /* @__PURE__ */ f(I, {
41
- ariaLabelClose: n.close_aria,
42
- isOpen: v,
43
- onClose: p,
44
- onPrimaryAction: () => s(!0),
45
- onSecondaryAction: () => m(!0),
46
- primaryText: t.details_edit_button,
47
- secondaryColor: "error",
48
- secondaryText: t.details_delete_button,
49
- title: t.details_title,
50
- children: [/* @__PURE__ */ o(j, { budget: e }), /* @__PURE__ */ o(k, {
51
- anchorOrigin: {
52
- vertical: "bottom",
53
- horizontal: "right"
54
- },
55
- autoHideDuration: 3500,
56
- onClose: () => a(""),
57
- open: !!d,
58
- children: /* @__PURE__ */ o(U, {
59
- closeText: "",
60
- onClose: () => a(""),
61
- severity: "success",
62
- variant: "filled",
63
- children: d
64
- })
65
- })]
66
- }),
67
- /* @__PURE__ */ o(_, {
68
- copy: {
69
- close_aria: n.close_aria,
70
- title: t.details_edit_title
71
- },
72
- disablePrimaryButton: Number(i) <= 0,
73
- isOpen: x,
74
- onClose: g,
75
- onPrimaryAction: T,
76
- onSecondaryAction: g,
77
- primaryText: t.edit_save_button,
78
- children: /* @__PURE__ */ o($, {
79
- amount: i,
80
- categoryName: e.category.name,
81
- onAmountChanged: l
82
- })
83
- }),
84
- /* @__PURE__ */ o(_, {
85
- copy: {
86
- close_aria: n.close_aria,
87
- title: t.delete_title
65
+ if (!e) return;
66
+ const f = e.subBudgets.length > 0, k = f ? e.subBudgets.some((o) => x(_[o.guid] ?? `${o.amount}`)) : x(n);
67
+ return /* @__PURE__ */ B(r.Fragment, { children: [
68
+ /* @__PURE__ */ B(H, {
69
+ ariaLabelClose: m.close_aria,
70
+ isOpen: P,
71
+ onClose: A,
72
+ onPrimaryAction: () => g(!0),
73
+ onSecondaryAction: () => y(!0),
74
+ primaryText: t.details_edit_button,
75
+ secondaryColor: "error",
76
+ secondaryText: t.details_delete_button,
77
+ title: t.details_title,
78
+ children: [/* @__PURE__ */ a(M, { budget: e }), /* @__PURE__ */ a(V, {
79
+ anchorOrigin: {
80
+ vertical: "bottom",
81
+ horizontal: "right"
88
82
  },
89
- isOpen: O,
90
- onClose: () => m(!1),
91
- onPrimaryAction: w,
92
- primaryColor: "error",
93
- primaryText: t.details_delete_button,
94
- secondaryColor: "secondary",
95
- children: /* @__PURE__ */ o(R, {
96
- variant: "subtitle1",
97
- children: c(t.delete_description, e.category.name)
83
+ autoHideDuration: 3500,
84
+ onClose: () => c(null),
85
+ open: !!l,
86
+ children: /* @__PURE__ */ a(Q, {
87
+ closeText: "",
88
+ onClose: () => c(null),
89
+ role: l?.severity === "error" ? "alert" : void 0,
90
+ severity: l?.severity ?? "success",
91
+ variant: "filled",
92
+ children: l?.msg
98
93
  })
94
+ })]
95
+ }),
96
+ /* @__PURE__ */ B(C, {
97
+ copy: {
98
+ close_aria: m.close_aria,
99
+ title: t.details_edit_title
100
+ },
101
+ disablePrimaryButton: k,
102
+ isOpen: $,
103
+ onClose: v,
104
+ onPrimaryAction: j,
105
+ onSecondaryAction: v,
106
+ primaryText: t.edit_save_button,
107
+ sx: { "& .MuiStack-root:first-of-type": { pb: 8 } },
108
+ children: [!f && /* @__PURE__ */ a(L, {
109
+ amount: n,
110
+ categoryName: e.category.name,
111
+ onAmountChanged: p
112
+ }), f && /* @__PURE__ */ a(q, {
113
+ categoryName: e.category.name,
114
+ onSubBudgetAmountChanged: (o, s) => b((i) => ({
115
+ ...i,
116
+ [o]: s
117
+ })),
118
+ subBudgetAmounts: _,
119
+ subBudgets: e.subBudgets
120
+ })]
121
+ }),
122
+ /* @__PURE__ */ a(C, {
123
+ copy: {
124
+ close_aria: m.close_aria,
125
+ title: t.delete_title
126
+ },
127
+ isOpen: I,
128
+ onClose: () => y(!1),
129
+ onPrimaryAction: G,
130
+ primaryColor: "error",
131
+ primaryText: t.details_delete_button,
132
+ secondaryColor: "secondary",
133
+ children: /* @__PURE__ */ a(K, {
134
+ variant: "subtitle1",
135
+ children: u(t.delete_description, e.category.name)
99
136
  })
100
- ] });
137
+ })
138
+ ] });
101
139
  });
102
140
  export {
103
- Z as BudgetDetailsDrawer
141
+ ce as BudgetDetailsDrawer
104
142
  };
105
143
 
106
144
  //# sourceMappingURL=BudgetDetailsDrawer.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BudgetDetailsDrawer.es.js","names":[],"sources":["../../../src/budgets/components/BudgetDetailsDrawer.tsx"],"sourcesContent":["import React from 'react'\n\nimport { observer } from 'mobx-react-lite'\n\nimport Alert from '@mui/material/Alert'\nimport Snackbar from '@mui/material/Snackbar'\n\nimport { Text } from '@mxenabled/mxui'\n\nimport {\n Dialog,\n Drawer,\n useBudgetsStore,\n useGlobalCopyStore,\n useGlobalUiStore,\n useTransactionStore,\n} from '../../common'\nimport { type Budget, type Transaction } from '../../core'\n\nimport { BudgetDetails } from './budgetdetails/BudgetDetails'\nimport { BudgetAmount } from './shared/BudgetAmount'\nimport { buildDynamicCopy } from '../../core/utils/Localization'\n\nexport const BudgetDetailsDrawer = observer(() => {\n const { selectedAccountGuids } = useGlobalUiStore()\n const { budgets: copy, common: commonCopy } = useGlobalCopyStore()\n const {\n alert,\n dateRange,\n deleteBudget,\n selectedBudget,\n selectedSubBudget,\n setAlert,\n setSelectedBudget,\n updateBudget,\n } = useBudgetsStore()\n const { setFilter } = useTransactionStore()\n\n const [isOpen, setIsOpen] = React.useState(false)\n const [isEditOpen, setIsEditOpen] = React.useState(false)\n const [isDeleteOpen, setIsDeleteOpen] = React.useState(false)\n const [amount, setAmount] = React.useState(``)\n\n React.useEffect(() => {\n if (selectedBudget && !selectedSubBudget) {\n setAmount(`${selectedBudget.amount}`)\n setIsOpen(true)\n setFilter({\n accounts: selectedAccountGuids,\n dateRange: dateRange,\n custom: (t: Transaction) =>\n t.category_guid === selectedBudget.category_guid ||\n t.top_level_category_guid === selectedBudget.category_guid,\n showSplits: true,\n })\n }\n }, [selectedBudget])\n\n const handleUpdateBudget = async () => {\n if (selectedBudget) {\n await updateBudget({\n ...selectedBudget,\n amount: Number(amount),\n percentage: (selectedBudget.category.totalAmount / Number(amount)) * 100,\n } as Budget)\n setIsEditOpen(false)\n setAlert(buildDynamicCopy(copy.alert_budget_updated, selectedBudget.category.name) as string)\n }\n }\n\n const handleDeleteBudget = async () => {\n if (selectedBudget) {\n await deleteBudget(selectedBudget.guid)\n setAlert(buildDynamicCopy(copy.alert_budget_deleted, selectedBudget.category.name) as string)\n }\n handleClose()\n }\n\n const handleClose = () => {\n setIsOpen(false)\n // Wait for the close animation before set the selected budget\n setTimeout(() => {\n setSelectedBudget(undefined)\n }, 250)\n }\n\n const handleEditClose = () => {\n setIsEditOpen(false)\n setAmount(`${selectedBudget?.amount}`)\n }\n\n if (!selectedBudget) {\n return undefined\n }\n\n return (\n <React.Fragment>\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isOpen}\n onClose={handleClose}\n onPrimaryAction={() => setIsEditOpen(true)}\n onSecondaryAction={() => setIsDeleteOpen(true)}\n primaryText={copy.details_edit_button}\n secondaryColor=\"error\"\n secondaryText={copy.details_delete_button}\n title={copy.details_title}\n >\n <BudgetDetails budget={selectedBudget} />\n <Snackbar\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n autoHideDuration={3500}\n onClose={() => setAlert('')}\n open={Boolean(alert)}\n >\n <Alert closeText=\"\" onClose={() => setAlert('')} severity={'success'} variant=\"filled\">\n {alert}\n </Alert>\n </Snackbar>\n </Drawer>\n\n <Dialog\n copy={{ close_aria: commonCopy.close_aria, title: copy.details_edit_title }}\n disablePrimaryButton={Number(amount) <= 0}\n isOpen={isEditOpen}\n onClose={handleEditClose}\n onPrimaryAction={handleUpdateBudget}\n onSecondaryAction={handleEditClose}\n primaryText={copy.edit_save_button}\n >\n <BudgetAmount\n amount={amount}\n categoryName={selectedBudget.category.name}\n onAmountChanged={setAmount}\n />\n </Dialog>\n\n <Dialog\n copy={{ close_aria: commonCopy.close_aria, title: copy.delete_title }}\n isOpen={isDeleteOpen}\n onClose={() => setIsDeleteOpen(false)}\n onPrimaryAction={handleDeleteBudget}\n primaryColor=\"error\"\n primaryText={copy.details_delete_button}\n secondaryColor=\"secondary\"\n >\n <Text variant=\"subtitle1\">\n {buildDynamicCopy(copy.delete_description, selectedBudget.category.name) as string}\n </Text>\n </Dialog>\n </React.Fragment>\n )\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"BudgetDetailsDrawer.es.js","names":[],"sources":["../../../src/budgets/components/BudgetDetailsDrawer.tsx"],"sourcesContent":["import React from 'react'\n\nimport { observer } from 'mobx-react-lite'\n\nimport Alert from '@mui/material/Alert'\nimport Snackbar from '@mui/material/Snackbar'\n\nimport { Text } from '@mxenabled/mxui'\n\nimport {\n Dialog,\n Drawer,\n useBudgetsStore,\n useGlobalCopyStore,\n useGlobalUiStore,\n useTransactionStore,\n} from '../../common'\nimport { type Budget, type DetailedBudget, type Transaction } from '../../core'\n\nimport { BudgetDetails } from './budgetdetails/BudgetDetails'\nimport { BudgetAmount } from './shared/BudgetAmount'\nimport { buildDynamicCopy } from '../../core/utils/Localization'\nimport { isInvalidAmount } from '../../core/utils/BudgetUtil'\nimport { SubBudgetAmounts } from './budgetdetails/SubBudgetAmounts'\n\nconst seedSubAmounts = (b?: DetailedBudget) =>\n Object.fromEntries((b?.subBudgets ?? []).map((sb) => [sb.guid, `${sb.amount}`]))\n\nexport const BudgetDetailsDrawer = observer(() => {\n const { selectedAccountGuids } = useGlobalUiStore()\n const { budgets: copy, common: commonCopy } = useGlobalCopyStore()\n const {\n alert,\n dateRange,\n deleteBudget,\n selectedBudget,\n selectedSubBudget,\n setAlert,\n setSelectedBudget,\n updateBudget,\n } = useBudgetsStore()\n const { setFilter } = useTransactionStore()\n\n const [isOpen, setIsOpen] = React.useState(false)\n const [isEditOpen, setIsEditOpen] = React.useState(false)\n const [isDeleteOpen, setIsDeleteOpen] = React.useState(false)\n const [amount, setAmount] = React.useState(``)\n const [subBudgetAmounts, setSubBudgetAmounts] = React.useState<Record<string, string>>({})\n\n React.useEffect(() => {\n if (selectedBudget && !selectedSubBudget) {\n setAmount(`${selectedBudget.amount}`)\n setSubBudgetAmounts(seedSubAmounts(selectedBudget))\n setIsOpen(true)\n setFilter({\n accounts: selectedAccountGuids,\n dateRange: dateRange,\n custom: (t: Transaction) =>\n t.category_guid === selectedBudget.category_guid ||\n t.top_level_category_guid === selectedBudget.category_guid,\n showSplits: true,\n })\n }\n }, [selectedBudget])\n\n const handleUpdateBudget = async () => {\n if (selectedBudget) {\n let allSucceeded = true\n\n if (selectedBudget.subBudgets.length > 0) {\n const results = await Promise.all(\n selectedBudget.subBudgets.map((subBudget) => {\n const newAmount = Number(subBudgetAmounts[subBudget.guid] ?? subBudget.amount)\n return updateBudget({\n ...subBudget,\n amount: newAmount,\n percentage: newAmount ? (subBudget.category.currentAmount / newAmount) * 100 : 0,\n } as Budget)\n }),\n )\n allSucceeded = results.every(Boolean)\n } else {\n const result = await updateBudget({\n ...selectedBudget,\n amount: Number(amount),\n percentage: Number(amount)\n ? (selectedBudget.category.totalAmount / Number(amount)) * 100\n : 0,\n } as Budget)\n allSucceeded = result\n }\n\n setAlert(\n allSucceeded\n ? {\n msg: buildDynamicCopy(\n copy.alert_budget_updated,\n selectedBudget.category.name,\n ) as string,\n severity: 'success',\n }\n : {\n msg: buildDynamicCopy(\n copy.error_alert_edit_merchant_budget,\n selectedBudget.category.name,\n ) as string,\n severity: 'error',\n },\n )\n setIsEditOpen(false)\n }\n }\n\n const handleDeleteBudget = async () => {\n if (selectedBudget) {\n const succeeded = await deleteBudget(selectedBudget.guid)\n setIsDeleteOpen(false)\n setAlert(\n succeeded\n ? {\n msg: buildDynamicCopy(\n copy.alert_budget_deleted,\n selectedBudget.category.name,\n ) as string,\n severity: 'success',\n }\n : {\n msg: buildDynamicCopy(\n copy.error_alert_delete_merchant_budget,\n selectedBudget.category.name,\n ) as string,\n severity: 'error',\n },\n )\n if (succeeded) {\n handleClose()\n }\n }\n }\n\n const handleClose = () => {\n setIsOpen(false)\n // Wait for the close animation before set the selected budget\n setTimeout(() => {\n setSelectedBudget(undefined)\n }, 250)\n }\n\n const handleEditClose = () => {\n setIsEditOpen(false)\n setAmount(`${selectedBudget?.amount}`)\n setSubBudgetAmounts(seedSubAmounts(selectedBudget))\n }\n\n if (!selectedBudget) {\n return undefined\n }\n\n const hasSubBudgets = selectedBudget.subBudgets.length > 0\n const disablePrimaryButton = hasSubBudgets\n ? selectedBudget.subBudgets.some((sb) =>\n isInvalidAmount(subBudgetAmounts[sb.guid] ?? `${sb.amount}`),\n )\n : isInvalidAmount(amount)\n\n return (\n <React.Fragment>\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isOpen}\n onClose={handleClose}\n onPrimaryAction={() => setIsEditOpen(true)}\n onSecondaryAction={() => setIsDeleteOpen(true)}\n primaryText={copy.details_edit_button}\n secondaryColor=\"error\"\n secondaryText={copy.details_delete_button}\n title={copy.details_title}\n >\n <BudgetDetails budget={selectedBudget} />\n <Snackbar\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n autoHideDuration={3500}\n onClose={() => setAlert(null)}\n open={Boolean(alert)}\n >\n <Alert\n closeText=\"\"\n onClose={() => setAlert(null)}\n role={alert?.severity === 'error' ? 'alert' : undefined}\n severity={alert?.severity ?? 'success'}\n variant=\"filled\"\n >\n {alert?.msg}\n </Alert>\n </Snackbar>\n </Drawer>\n\n <Dialog\n copy={{ close_aria: commonCopy.close_aria, title: copy.details_edit_title }}\n disablePrimaryButton={disablePrimaryButton}\n isOpen={isEditOpen}\n onClose={handleEditClose}\n onPrimaryAction={handleUpdateBudget}\n onSecondaryAction={handleEditClose}\n primaryText={copy.edit_save_button}\n sx={{\n '& .MuiStack-root:first-of-type': {\n pb: 8,\n },\n }}\n >\n {!hasSubBudgets && (\n <BudgetAmount\n amount={amount}\n categoryName={selectedBudget.category.name}\n onAmountChanged={setAmount}\n />\n )}\n {hasSubBudgets && (\n <SubBudgetAmounts\n categoryName={selectedBudget.category.name}\n onSubBudgetAmountChanged={(guid, v) =>\n setSubBudgetAmounts((p) => ({ ...p, [guid]: v }))\n }\n subBudgetAmounts={subBudgetAmounts}\n subBudgets={selectedBudget.subBudgets}\n />\n )}\n </Dialog>\n\n <Dialog\n copy={{ close_aria: commonCopy.close_aria, title: copy.delete_title }}\n isOpen={isDeleteOpen}\n onClose={() => setIsDeleteOpen(false)}\n onPrimaryAction={handleDeleteBudget}\n primaryColor=\"error\"\n primaryText={copy.details_delete_button}\n secondaryColor=\"secondary\"\n >\n <Text variant=\"subtitle1\">\n {buildDynamicCopy(copy.delete_description, selectedBudget.category.name) as string}\n </Text>\n </Dialog>\n </React.Fragment>\n )\n})\n"],"mappings":"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"}
@@ -20,9 +20,9 @@ var c = {
20
20
  END_DELETE: "End - Delete",
21
21
  START_DELETE: "Start - Delete"
22
22
  }, re = ({ onClose: A, onEvent: s, onViewHistory: L, transactionListProps: x }) => {
23
- const { alert: u, dateRange: f, deleteBudget: B, selectedBudget: e, selectedSubBudget: N, setAlert: m, setSelectedBudget: v, updateBudget: w } = z(), { budgets: o, common: p } = M(), { isCopyLoaded: G, selectedAccountGuids: R } = k(), E = ee(), { setFilter: V } = H(), [a, d] = i.useState(""), [t, n] = i.useState(null), [P, C] = i.useState(!1), g = i.useRef(!1);
23
+ const { alert: d, dateRange: f, deleteBudget: B, selectedBudget: e, selectedSubBudget: v, setAlert: m, setSelectedBudget: N, updateBudget: w } = z(), { budgets: o, common: p } = M(), { isCopyLoaded: G, selectedAccountGuids: R } = k(), E = ee(), { setFilter: V } = H(), [a, u] = i.useState(""), [t, n] = i.useState(null), [P, C] = i.useState(!1), g = i.useRef(!1);
24
24
  if (i.useEffect(() => {
25
- !e || N || (d(`${e.amount}`), V({
25
+ !e || v || (u(`${e.amount}`), V({
26
26
  accounts: R,
27
27
  dateRange: f,
28
28
  custom: ({ category_guid: l, top_level_category_guid: y }) => {
@@ -33,18 +33,21 @@ var c = {
33
33
  }, [e]), !G) return /* @__PURE__ */ r(q, {});
34
34
  if (!e) return null;
35
35
  const b = () => {
36
- d(""), n(null), C(!1), setTimeout(() => {
37
- v(void 0), A?.();
36
+ u(""), n(null), C(!1), setTimeout(() => {
37
+ N(void 0), A?.();
38
38
  }, 250);
39
39
  }, S = () => {
40
- t === "delete" && s?.(c.CANCEL_DELETE, a), d(e.amount ? `${e.amount}` : ""), n(null);
40
+ t === "delete" && s?.(c.CANCEL_DELETE, a), u(e.amount ? `${e.amount}` : ""), n(null);
41
41
  }, F = async () => {
42
42
  if (t === "edit") {
43
43
  if (g.current) return;
44
44
  g.current = !0, await w({
45
45
  ...e,
46
46
  amount: Number(a)
47
- }), s?.(c.END_SAVE, a), m(_(o.alert_budget_updated, e.category.name)), n(null), g.current = !1;
47
+ }), s?.(c.END_SAVE, a), m({
48
+ msg: _(o.alert_budget_updated, e.category.name),
49
+ severity: "success"
50
+ }), n(null), g.current = !1;
48
51
  }
49
52
  t === "delete" && (await B(e.guid), s?.(c.END_DELETE, a), b());
50
53
  }, { remainingAmount: O, spentPercentage: $, iconColor: I } = W(e.transaction_total ?? 0, e.amount ?? 0), j = (l, y) => _(l, /* @__PURE__ */ r("b", { children: y }));
@@ -85,27 +88,27 @@ var c = {
85
88
  totalTransaction: e.transaction_total
86
89
  }),
87
90
  /* @__PURE__ */ r(K, { ...x }),
88
- u && /* @__PURE__ */ r(oe, {
91
+ d && /* @__PURE__ */ r(oe, {
89
92
  anchorOrigin: {
90
93
  horizontal: "right",
91
94
  vertical: "bottom"
92
95
  },
93
96
  autoHideDuration: 3500,
94
- onClose: () => m(""),
95
- open: !!u,
97
+ onClose: () => m(null),
98
+ open: !!d,
96
99
  children: /* @__PURE__ */ r(te, {
97
100
  closeText: "",
98
- onClose: () => m(""),
99
- severity: "success",
101
+ onClose: () => m(null),
102
+ severity: d?.severity ?? "success",
100
103
  variant: "filled",
101
- children: u
104
+ children: d?.msg
102
105
  })
103
106
  })
104
107
  ]
105
108
  }), t && /* @__PURE__ */ r(J, {
106
109
  closeAriaLabel: p.close_aria,
107
110
  content: j(o[t === "edit" ? "edit_budget_content" : "delete_description"], e.category.name),
108
- handleInputChange: (l) => d(l.toString()),
111
+ handleInputChange: (l) => u(l.toString()),
109
112
  handleModalClose: S,
110
113
  handlePrimaryAction: F,
111
114
  handleSecondaryAction: S,