@mx-cartographer/experiences 9.4.1-alpha.al0 → 9.4.2

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 (43) hide show
  1. package/CHANGELOG.md +8 -2
  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 +95 -95
  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 +63 -61
  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 +3 -4
  17. package/dist/budgets/components/budgetdetails/SubBudgetAmounts.es.js +42 -31
  18. package/dist/budgets/components/budgetdetails/SubBudgetAmounts.es.js.map +1 -1
  19. package/dist/budgets/components/budgetdetails/SubBudgetList.es.js +71 -59
  20. package/dist/budgets/components/budgetdetails/SubBudgetList.es.js.map +1 -1
  21. package/dist/budgets/components/shared/SubBudgetCategory.d.ts +2 -2
  22. package/dist/budgets/components/shared/SubBudgetCategory.es.js.map +1 -1
  23. package/dist/core/stores/BudgetsStore.d.ts +13 -6
  24. package/dist/core/stores/BudgetsStore.es.js +36 -42
  25. package/dist/core/stores/BudgetsStore.es.js.map +1 -1
  26. package/dist/core/types/RepeatingTransaction.d.ts +2 -2
  27. package/dist/core/types/RepeatingTransaction.es.js.map +1 -1
  28. package/dist/core/utils/BudgetUtil.d.ts +1 -0
  29. package/dist/core/utils/BudgetUtil.es.js +55 -57
  30. package/dist/core/utils/BudgetUtil.es.js.map +1 -1
  31. package/dist/recurringtransactions/components/RecurrenceRow.es.js +1 -1
  32. package/dist/recurringtransactions/components/RecurrenceRow.es.js.map +1 -1
  33. package/dist/recurringtransactions/components/RecurringTransactionDetails.es.js +1 -1
  34. package/dist/recurringtransactions/components/RecurringTransactionDetails.es.js.map +1 -1
  35. package/dist/recurringtransactions/components/RecurringTransactionList.es.js +1 -1
  36. package/dist/recurringtransactions/components/RecurringTransactionList.es.js.map +1 -1
  37. package/dist/recurringtransactions/components/shared/recurringsettings/RecurringRow.es.js +1 -1
  38. package/dist/recurringtransactions/components/shared/recurringsettings/RecurringRow.es.js.map +1 -1
  39. package/dist/recurringtransactions/components/shared/recurringsettings/SelectTransaction.es.js +14 -15
  40. package/dist/recurringtransactions/components/shared/recurringsettings/SelectTransaction.es.js.map +1 -1
  41. package/dist/transactions/components/shared/transactiondetails/actions/AddMerchantBudgetAction.es.js +85 -82
  42. package/dist/transactions/components/shared/transactiondetails/actions/AddMerchantBudgetAction.es.js.map +1 -1
  43. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,7 +1,13 @@
1
+ ## [9.4.2] - 08-26-2026
1
2
 
2
- ## [9.4.1] - 08-25-2026
3
+ - **ADDED** - Sub budget totals now roll up to parent budget total
4
+ - **ADDED** - Destructive cascade delete of sub-budgets when a parent budget is deleted
5
+ - **REMOVED** - Un-budgeted projected income line
6
+ - **CHANGED** - Colors from `primary.light` to `primary.main`
3
7
 
4
- - **UPDATED** - Sub budget totals now roll up to parent budget total
8
+ ## [9.4.1] - 08-26-2026
9
+
10
+ - **REMOVED** - Merchant Guid filter when adding recurring transactions
5
11
 
6
12
  ## [9.4.0] - 08-25-2026
7
13
 
@@ -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":"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"}
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,144 +1,144 @@
1
- import { buildDynamicCopy as b } from "../../core/utils/Localization.es.js";
2
- import { useBudgetsStore as H, useGlobalCopyStore as L, useGlobalUiStore as M, useTransactionStore as q } from "../../common/context/hooks.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
3
  import C from "../../common/components/dialog/Dialog.es.js";
4
- import J from "../../common/components/drawer/Drawer.es.js";
5
- import { BudgetAmount as K } from "./shared/BudgetAmount.es.js";
6
- import { BudgetDetails as Q } from "./budgetdetails/BudgetDetails.es.js";
7
- import { SubBudgetAmounts as V } from "./budgetdetails/SubBudgetAmounts.es.js";
8
- import s from "react";
9
- import { observer as W } from "mobx-react-lite";
10
- import { Text as X } from "@mxenabled/mxui";
11
- import { jsx as n, jsxs as y } from "react/jsx-runtime";
12
- import Y from "@mui/material/Alert";
13
- import Z from "@mui/material/Snackbar";
14
- var ge = W(() => {
15
- const { selectedAccountGuids: v } = M(), { budgets: r, common: m } = L(), { alert: f, dateRange: N, deleteBudget: x, selectedBudget: e, selectedSubBudget: D, setAlert: u, setSelectedBudget: O, updateBudget: _ } = H(), { setFilter: T } = q(), [w, S] = s.useState(!1), [E, g] = s.useState(!1), [P, B] = s.useState(!1), [a, d] = s.useState(""), [c, p] = s.useState({});
16
- s.useEffect(() => {
17
- if (e && !D) {
18
- d(`${e.amount}`);
19
- const o = {};
20
- e.subBudgets.forEach((t) => {
21
- o[t.guid] = `${t.amount}`;
22
- }), p(o), S(!0), T({
23
- accounts: v,
24
- dateRange: N,
25
- custom: (t) => t.category_guid === e.category_guid || t.top_level_category_guid === e.category_guid,
26
- showSplits: !0
27
- });
28
- }
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";
9
+ import r from "react";
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({});
17
+ r.useEffect(() => {
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,
22
+ showSplits: !0
23
+ }));
29
24
  }, [e]);
30
- const $ = (o, t) => {
31
- const i = {
32
- ...c,
33
- [o]: t
34
- }, R = e?.subBudgets.reduce((U, z) => U + (Number(i[z.guid]) || 0), 0);
35
- p(i), d(`${R ?? 0}`);
36
- }, I = async () => {
25
+ const j = async () => {
37
26
  if (e) {
38
27
  let o = !0;
39
- e.subBudgets.length > 0 ? o = (await Promise.all(e.subBudgets.map((t) => {
40
- const i = Number(c[t.guid] ?? t.amount);
41
- return _({
42
- ...t,
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,
43
32
  amount: i,
44
- percentage: t.category.currentAmount / (i || 1) * 100
33
+ percentage: i ? s.category.currentAmount / i * 100 : 0
45
34
  });
46
- }))).every((t) => t.isSuccess) : o = (await _({
35
+ }))).every(Boolean) : o = await h({
47
36
  ...e,
48
- amount: Number(a),
49
- percentage: e.category.totalAmount / (Number(a) || 1) * 100
50
- })).isSuccess, o && (g(!1), u(b(r.alert_budget_updated, e.category.name)));
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);
51
46
  }
52
47
  }, G = async () => {
53
- e && (await x(e.guid), u(b(r.alert_budget_deleted, e.category.name))), h();
54
- }, h = () => {
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 = () => {
55
59
  S(!1), setTimeout(() => {
56
- O(void 0);
60
+ N(void 0);
57
61
  }, 250);
58
- }, A = () => {
59
- g(!1), d(`${e?.amount}`);
60
- const o = {};
61
- e?.subBudgets.forEach((t) => {
62
- o[t.guid] = `${t.amount}`;
63
- }), p(o);
62
+ }, v = () => {
63
+ g(!1), p(`${e?.amount}`), b(D(e));
64
64
  };
65
65
  if (!e) return;
66
- const l = e.subBudgets.length > 0, j = a === "" || Number(a) < 0 || isNaN(Number(a)), k = l && e.subBudgets.some((o) => {
67
- const t = c[o.guid];
68
- return t === void 0 || t === "" || Number(t) < 0 || isNaN(Number(t));
69
- }), F = l ? k : j;
70
- return /* @__PURE__ */ y(s.Fragment, { children: [
71
- /* @__PURE__ */ y(J, {
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, {
72
69
  ariaLabelClose: m.close_aria,
73
- isOpen: w,
74
- onClose: h,
70
+ isOpen: P,
71
+ onClose: A,
75
72
  onPrimaryAction: () => g(!0),
76
- onSecondaryAction: () => B(!0),
77
- primaryText: r.details_edit_button,
73
+ onSecondaryAction: () => y(!0),
74
+ primaryText: t.details_edit_button,
78
75
  secondaryColor: "error",
79
- secondaryText: r.details_delete_button,
80
- title: r.details_title,
81
- children: [/* @__PURE__ */ n(Q, { budget: e }), /* @__PURE__ */ n(Z, {
76
+ secondaryText: t.details_delete_button,
77
+ title: t.details_title,
78
+ children: [/* @__PURE__ */ a(M, { budget: e }), /* @__PURE__ */ a(V, {
82
79
  anchorOrigin: {
83
80
  vertical: "bottom",
84
81
  horizontal: "right"
85
82
  },
86
83
  autoHideDuration: 3500,
87
- onClose: () => u(""),
88
- open: !!f,
89
- children: /* @__PURE__ */ n(Y, {
84
+ onClose: () => c(null),
85
+ open: !!l,
86
+ children: /* @__PURE__ */ a(Q, {
90
87
  closeText: "",
91
- onClose: () => u(""),
92
- severity: "success",
88
+ onClose: () => c(null),
89
+ role: l?.severity === "error" ? "alert" : void 0,
90
+ severity: l?.severity ?? "success",
93
91
  variant: "filled",
94
- children: f
92
+ children: l?.msg
95
93
  })
96
94
  })]
97
95
  }),
98
- /* @__PURE__ */ y(C, {
96
+ /* @__PURE__ */ B(C, {
99
97
  copy: {
100
98
  close_aria: m.close_aria,
101
- title: r.details_edit_title
99
+ title: t.details_edit_title
102
100
  },
103
- disablePrimaryButton: F,
104
- isOpen: E,
105
- onClose: A,
106
- onPrimaryAction: I,
107
- onSecondaryAction: A,
108
- primaryText: r.edit_save_button,
109
- sx: { "& .MuiStack-root:first-child": { pb: 8 } },
110
- children: [!l && /* @__PURE__ */ n(K, {
111
- amount: a,
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,
112
110
  categoryName: e.category.name,
113
- onAmountChanged: d
114
- }), l && /* @__PURE__ */ n(V, {
115
- amount: a,
111
+ onAmountChanged: p
112
+ }), f && /* @__PURE__ */ a(q, {
116
113
  categoryName: e.category.name,
117
- onSubBudgetAmountChanged: $,
118
- subBudgetAmounts: c,
114
+ onSubBudgetAmountChanged: (o, s) => b((i) => ({
115
+ ...i,
116
+ [o]: s
117
+ })),
118
+ subBudgetAmounts: _,
119
119
  subBudgets: e.subBudgets
120
120
  })]
121
121
  }),
122
- /* @__PURE__ */ n(C, {
122
+ /* @__PURE__ */ a(C, {
123
123
  copy: {
124
124
  close_aria: m.close_aria,
125
- title: r.delete_title
125
+ title: t.delete_title
126
126
  },
127
- isOpen: P,
128
- onClose: () => B(!1),
127
+ isOpen: I,
128
+ onClose: () => y(!1),
129
129
  onPrimaryAction: G,
130
130
  primaryColor: "error",
131
- primaryText: r.details_delete_button,
131
+ primaryText: t.details_delete_button,
132
132
  secondaryColor: "secondary",
133
- children: /* @__PURE__ */ n(X, {
133
+ children: /* @__PURE__ */ a(K, {
134
134
  variant: "subtitle1",
135
- children: b(r.delete_description, e.category.name)
135
+ children: u(t.delete_description, e.category.name)
136
136
  })
137
137
  })
138
138
  ] });
139
139
  });
140
140
  export {
141
- ge as BudgetDetailsDrawer
141
+ ce as BudgetDetailsDrawer
142
142
  };
143
143
 
144
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'\nimport { SubBudgetAmounts } from './budgetdetails/SubBudgetAmounts'\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 const initialSubAmounts: Record<string, string> = {}\n selectedBudget.subBudgets.forEach((sb) => {\n initialSubAmounts[sb.guid] = `${sb.amount}`\n })\n setSubBudgetAmounts(initialSubAmounts)\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 handleSubBudgetAmountChanged = (guid: string, newAmount: string) => {\n const updated = { ...subBudgetAmounts, [guid]: newAmount }\n const newTotal = selectedBudget?.subBudgets.reduce(\n (sum, sb) => sum + (Number(updated[sb.guid]) || 0),\n 0,\n )\n setSubBudgetAmounts(updated)\n setAmount(`${newTotal ?? 0}`)\n }\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: (subBudget.category.currentAmount / (newAmount || 1)) * 100,\n } as Budget)\n }),\n )\n allSucceeded = results.every((r) => r.isSuccess)\n } else {\n const result = await updateBudget({\n ...selectedBudget,\n amount: Number(amount),\n percentage: (selectedBudget.category.totalAmount / (Number(amount) || 1)) * 100,\n } as Budget)\n allSucceeded = result.isSuccess\n }\n\n if (allSucceeded) {\n setIsEditOpen(false)\n setAlert(\n buildDynamicCopy(copy.alert_budget_updated, selectedBudget.category.name) as string,\n )\n }\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 const initialSubAmounts: Record<string, string> = {}\n selectedBudget?.subBudgets.forEach((sb) => {\n initialSubAmounts[sb.guid] = `${sb.amount}`\n })\n setSubBudgetAmounts(initialSubAmounts)\n }\n\n if (!selectedBudget) {\n return undefined\n }\n\n const hasSubBudgets = selectedBudget.subBudgets.length > 0\n const isParentInvalid = amount === '' || Number(amount) < 0 || isNaN(Number(amount))\n const isSubBudgetInvalid =\n hasSubBudgets &&\n selectedBudget.subBudgets.some((sb) => {\n const val = subBudgetAmounts[sb.guid]\n return val === undefined || val === '' || Number(val) < 0 || isNaN(Number(val))\n })\n const disablePrimaryButton = hasSubBudgets ? isSubBudgetInvalid : isParentInvalid\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={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-child': {\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 amount={amount}\n categoryName={selectedBudget.category.name}\n onSubBudgetAmountChanged={handleSubBudgetAmountChanged}\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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"}
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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"}