@mx-cartographer/experiences 9.3.0 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [9.3.1] - 08-10-2026
2
+
3
+ - **FIXED** - Spending, Trends, Finstrong, and Budgets category totals used the viewer's local-midnight timestamps, shifting the query window by the timezone offset for non-UTC users and dropping/gaining boundary transactions; date-range boundaries are now sent as UTC calendar days
4
+
1
5
  ## [9.3.0] - 08-06-2026
2
6
 
3
7
  - **CHANGED** - Phase 1 toolchain modernization: upgraded to Vite 8, Vitest 4, and Storybook 10 (MEW-3727)
@@ -15,7 +19,6 @@
15
19
  - **CHANGED** - Pinned `msw` to an exact `2.15.0` to match the vendored `mockServiceWorker.js`, and `Beats.js` → `Beats.ts`
16
20
  - **ADDED** - `src/core/api/__tests__/ApiClasses.test.ts` exercising the real `src/core/api/*` classes against MSW; coverage now includes `src/core/api/**` in the denominator (the MSW migration runs the real API classes) with the REVIEW.md floors kept at lines 85 / statements 85 / functions 80 / branches 78 (tests added to clear them rather than lowering), and `coverage.cleanOnRerun` set to `true` so a re-run can't satisfy the floors with stale data
17
21
  - **CHANGED** - Dependency/structure hygiene: removed the unused `path` userland shim (configs use `node:path`); documented why `@typescript/typescript6` is retained (vite-plugin-dts needs the JS Compiler API that TS 7 native doesn't yet expose); consolidated the root `mockData/` fixtures into `mock/data/`
18
-
19
22
  ## [9.2.9] - 08-09-2026
20
23
 
21
24
  - **FIXED** - Category selector drawer kept the previously expanded accordion and highlighted selection when reopened for a different transaction; it now resets and expands to the current transaction's category each time it opens
@@ -24,8 +24,8 @@ import { Fragment as G, jsx as e, jsxs as i } from "react/jsx-runtime";
24
24
  import { keyframes as Te, useTheme as Ce } from "@mui/material/styles";
25
25
  import p from "@mui/material/Box";
26
26
  import { subDays as ke } from "date-fns/subDays";
27
- import { getUnixTime as Ie } from "date-fns/getUnixTime";
28
27
  import { fromUnixTime as U } from "date-fns/fromUnixTime";
28
+ import { getUnixTime as Ie } from "date-fns/getUnixTime";
29
29
  import { formatISO as we } from "date-fns/formatISO";
30
30
  import L from "@mui/material/Divider";
31
31
  import ve from "@mui/material/List";
@@ -1,11 +1,11 @@
1
1
  import { CategoryGuidToName as C, CategoryGuids as n } from "../constants/Category.es.js";
2
2
  import { CategoryApi as d } from "../api/CategoryApi.es.js";
3
3
  import { augmentCategories as T, getDetailedCategoryTransactions as S } from "../utils/CategoryUtil.es.js";
4
+ import { toUnixUTC as l } from "../utils/DateUtil.es.js";
4
5
  import { endOfMonth as c } from "date-fns/endOfMonth";
5
6
  import { startOfMonth as m } from "date-fns/startOfMonth";
6
7
  import { subMonths as h } from "date-fns/subMonths";
7
8
  import { makeAutoObservable as u, runInAction as g } from "mobx";
8
- import { getUnixTime as l } from "date-fns/getUnixTime";
9
9
  var I = class {
10
10
  globalStore;
11
11
  uiStore;
@@ -21,8 +21,8 @@ var I = class {
21
21
  monthlyTotalsLoading = !1;
22
22
  dateRangeTotalsRequestId = 0;
23
23
  monthlyTotalsRequestId = 0;
24
- constructor(e) {
25
- this.globalStore = e, this.uiStore = new p(), this.api = new d(e.endpoint, e.sessionToken, e.onError), u(this, {
24
+ constructor(t) {
25
+ this.globalStore = t, this.uiStore = new p(), this.api = new d(t.endpoint, t.sessionToken, t.onError), u(this, {
26
26
  dateRangeTotalsRequestId: !1,
27
27
  monthlyTotalsRequestId: !1
28
28
  });
@@ -34,30 +34,30 @@ var I = class {
34
34
  return S(this.detailedCategories, this.globalStore.transactionStore.sortedTransactions);
35
35
  }
36
36
  get incomeCategories() {
37
- return this.detailedCategories.filter((e) => e.is_income);
37
+ return this.detailedCategories.filter((t) => t.is_income);
38
38
  }
39
39
  get spendCategories() {
40
- return this.detailedCategories.filter((e) => !e.is_income && !e.isTransfer && e.guid !== n.INVESTMENTS);
40
+ return this.detailedCategories.filter((t) => !t.is_income && !t.isTransfer && t.guid !== n.INVESTMENTS);
41
41
  }
42
42
  get transferCategories() {
43
- return this.detailedCategories.filter((e) => e.isTransfer);
43
+ return this.detailedCategories.filter((t) => t.isTransfer);
44
44
  }
45
- setCategories = (e) => {
46
- this.categories = e, this.categoriesLoading = !1, this.categoriesLoaded = !0;
45
+ setCategories = (t) => {
46
+ this.categories = t, this.categoriesLoading = !1, this.categoriesLoaded = !0;
47
47
  };
48
- setMonthlyCategoryTotals = (e) => {
49
- this.monthlyCategoryTotals = e, this.monthlyTotalsLoading = !1, this.monthlyTotalsLoaded = !0;
48
+ setMonthlyCategoryTotals = (t) => {
49
+ this.monthlyCategoryTotals = t, this.monthlyTotalsLoading = !1, this.monthlyTotalsLoaded = !0;
50
50
  };
51
- setDateRangeCategoryTotals = (e) => {
52
- this.dateRangeCategoryTotals = e, this.dateRangeTotalsLoading = !1, this.dateRangeTotalsLoaded = !0;
51
+ setDateRangeCategoryTotals = (t) => {
52
+ this.dateRangeCategoryTotals = t, this.dateRangeTotalsLoading = !1, this.dateRangeTotalsLoaded = !0;
53
53
  };
54
54
  get trendsCategories() {
55
- return this.detailedCategories.filter((e) => e.totalAmount !== 0).filter((e) => e.guid !== n.INVESTMENTS && e.guid !== n.TRANSFER);
55
+ return this.detailedCategories.filter((t) => t.totalAmount !== 0).filter((t) => t.guid !== n.INVESTMENTS && t.guid !== n.TRANSFER);
56
56
  }
57
- addCategory = async (e, t) => {
57
+ addCategory = async (t, e) => {
58
58
  const r = {
59
- name: e,
60
- parent_guid: t
59
+ name: t,
60
+ parent_guid: e
61
61
  };
62
62
  try {
63
63
  await this.api.addCategory(r), await this.loadCategories();
@@ -69,22 +69,22 @@ var I = class {
69
69
  if (!this.categoriesLoading) {
70
70
  this.categoriesLoading = !0;
71
71
  try {
72
- const e = await this.api.getCategories();
73
- this.setCategories(e);
74
- } catch (e) {
75
- console.error("Error occurred while getting categories:", e), this.globalStore.captureException(e, { store: "CategoryStore" }), g(() => {
72
+ const t = await this.api.getCategories();
73
+ this.setCategories(t);
74
+ } catch (t) {
75
+ console.error("Error occurred while getting categories:", t), this.globalStore.captureException(t, { store: "CategoryStore" }), g(() => {
76
76
  this.categoriesLoading = !1;
77
77
  });
78
78
  }
79
79
  }
80
80
  };
81
- loadDateRangeCategoryTotals = async (e, t, r) => {
81
+ loadDateRangeCategoryTotals = async (t, e, r) => {
82
82
  const a = ++this.dateRangeTotalsRequestId, o = () => a !== this.dateRangeTotalsRequestId;
83
83
  g(() => {
84
84
  this.dateRangeTotalsLoading = !0;
85
85
  });
86
86
  try {
87
- const s = await this.api.getDateRangeCategoryTotals(l(t), l(r), e);
87
+ const s = await this.api.getDateRangeCategoryTotals(l(e), l(r), t);
88
88
  if (o()) return;
89
89
  this.setDateRangeCategoryTotals(s);
90
90
  } catch (s) {
@@ -92,14 +92,14 @@ var I = class {
92
92
  console.error("Error occurred while getting date range category totals:", s), this.globalStore.captureException(s, { store: "CategoryStore" }), this.setDateRangeCategoryTotals([]);
93
93
  }
94
94
  };
95
- loadMonthlyCategoryTotals = async (e = this.globalStore.globalUiStore.selectedAccounts, t, r) => {
95
+ loadMonthlyCategoryTotals = async (t = this.globalStore.globalUiStore.selectedAccounts, e, r) => {
96
96
  const a = ++this.monthlyTotalsRequestId, o = () => a !== this.monthlyTotalsRequestId;
97
97
  g(() => {
98
98
  this.monthlyTotalsLoading = !0;
99
99
  });
100
- const s = l(m(t ?? h(/* @__PURE__ */ new Date(), 11))), y = l(c(r ?? /* @__PURE__ */ new Date()));
100
+ const s = l(m(e ?? h(/* @__PURE__ */ new Date(), 11))), y = l(c(r ?? /* @__PURE__ */ new Date()));
101
101
  try {
102
- const i = await this.api.getMonthlyCategoryTotals(s, y, e);
102
+ const i = await this.api.getMonthlyCategoryTotals(s, y, t);
103
103
  if (o()) return;
104
104
  this.setMonthlyCategoryTotals(i);
105
105
  } catch (i) {
@@ -107,25 +107,25 @@ var I = class {
107
107
  console.error("Error occurred while getting monthly category totals:", i), this.globalStore.captureException(i, { store: "CategoryStore" }), this.setMonthlyCategoryTotals([]);
108
108
  }
109
109
  };
110
- reloadCategoryTotals = async (e, t, r) => {
111
- const a = t ?? h(/* @__PURE__ */ new Date(), 11), o = r ?? c(/* @__PURE__ */ new Date());
112
- await Promise.all([this.loadMonthlyCategoryTotals(e, a, o), this.loadDateRangeCategoryTotals(e, a, o)]);
110
+ reloadCategoryTotals = async (t, e, r) => {
111
+ const a = e ?? h(/* @__PURE__ */ new Date(), 11), o = r ?? c(/* @__PURE__ */ new Date());
112
+ await Promise.all([this.loadMonthlyCategoryTotals(t, a, o), this.loadDateRangeCategoryTotals(t, a, o)]);
113
113
  };
114
- removeCategory = async (e) => {
114
+ removeCategory = async (t) => {
115
115
  try {
116
- await this.api.removeCategory(e), await this.loadCategories();
117
- } catch (t) {
118
- console.error("Error occurred while removing category:", t), this.globalStore.captureException(t, { store: "CategoryStore" });
116
+ await this.api.removeCategory(t), await this.loadCategories();
117
+ } catch (e) {
118
+ console.error("Error occurred while removing category:", e), this.globalStore.captureException(e, { store: "CategoryStore" });
119
119
  }
120
120
  };
121
- updateCategory = async (e) => {
121
+ updateCategory = async (t) => {
122
122
  try {
123
- await this.api.updateCategory(e), await this.loadCategories();
124
- } catch (t) {
125
- console.error("Error occurred while updating category:", t), this.globalStore.captureException(t, { store: "CategoryStore" });
123
+ await this.api.updateCategory(t), await this.loadCategories();
124
+ } catch (e) {
125
+ console.error("Error occurred while updating category:", e), this.globalStore.captureException(e, { store: "CategoryStore" });
126
126
  }
127
127
  };
128
- getCategoryName = (e) => this.categories.find((t) => t.guid === e)?.name ?? C[e];
128
+ getCategoryName = (t) => this.categories.find((e) => e.guid === t)?.name ?? C[t];
129
129
  }, p = class {
130
130
  expandedGuid = null;
131
131
  selectedGuid = null;
@@ -138,15 +138,15 @@ var I = class {
138
138
  constructor() {
139
139
  u(this);
140
140
  }
141
- setExpandedGuid = (e) => this.expandedGuid = e;
142
- setSelectedGuid = (e) => this.selectedGuid = e;
143
- setSearchValue = (e) => this.searchValue = e;
144
- setShouldDisableDrawerScroll = (e) => this.shouldDisableDrawerScroll = e;
145
- setShowSelected = (e) => this.showSelected = e;
146
- setUnselectable = (e) => this.unselectable = e;
147
- setUnselectableText = (e) => this.unselectableText = e;
148
- onSelect = (e) => this.savedOnSelect(e);
149
- setOnSelect = (e) => this.savedOnSelect = e;
141
+ setExpandedGuid = (t) => this.expandedGuid = t;
142
+ setSelectedGuid = (t) => this.selectedGuid = t;
143
+ setSearchValue = (t) => this.searchValue = t;
144
+ setShouldDisableDrawerScroll = (t) => this.shouldDisableDrawerScroll = t;
145
+ setShowSelected = (t) => this.showSelected = t;
146
+ setUnselectable = (t) => this.unselectable = t;
147
+ setUnselectableText = (t) => this.unselectableText = t;
148
+ onSelect = (t) => this.savedOnSelect(t);
149
+ setOnSelect = (t) => this.savedOnSelect = t;
150
150
  };
151
151
  export {
152
152
  I as CategoryStore
@@ -1 +1 @@
1
- {"version":3,"file":"CategoryStore.es.js","names":[],"sources":["../../../src/core/stores/CategoryStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\nimport { getUnixTime } from 'date-fns/getUnixTime'\nimport { subMonths } from 'date-fns/subMonths'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { endOfMonth } from 'date-fns/endOfMonth'\n\nimport { CategoryGuids, CategoryGuidToName } from '../constants'\nimport { CategoryApi } from '../api'\n\nimport { GlobalStore } from './GlobalStore'\n\nimport type {\n Account,\n Category,\n DetailedCategory,\n DetailedCategoryWithTransactions,\n DateRangeCategoryTotals,\n MonthlyCategoryTotals,\n} from '../types'\n\nimport { augmentCategories, getDetailedCategoryTransactions } from '../utils/CategoryUtil'\n\nexport class CategoryStore {\n globalStore: GlobalStore\n uiStore: UiStore\n api = new CategoryApi('/', '')\n\n categories: Category[] = []\n categoriesLoaded: boolean = false\n categoriesLoading: boolean = false\n dateRangeCategoryTotals: DateRangeCategoryTotals[] = []\n monthlyCategoryTotals: MonthlyCategoryTotals[] = []\n\n dateRangeTotalsLoaded = false\n dateRangeTotalsLoading = false\n monthlyTotalsLoaded = false\n monthlyTotalsLoading = false\n\n // Monotonic request tokens, one per totals endpoint. A newer request\n // supersedes an older in-flight one: the stale response is discarded rather\n // than the newer request being dropped. These loaders used to early-return\n // while a request was in flight, which silently swallowed date-range/account\n // changes made mid-flight. (MEW-3910)\n //\n // Deliberately per-endpoint rather than one shared counter: several callers\n // (BubbleBudgetsWidget, BubbleBudgetsMiniWidget) fire the two loaders\n // independently and concurrently, and a shared counter would make the second\n // call supersede — and silently drop — the first.\n //\n // Kept out of the observable graph — internal concurrency bookkeeping, not\n // renderable state.\n dateRangeTotalsRequestId = 0\n monthlyTotalsRequestId = 0\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new CategoryApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this, {\n dateRangeTotalsRequestId: false,\n monthlyTotalsRequestId: false,\n })\n }\n\n get detailedCategories(): DetailedCategory[] {\n if (!this.globalStore.isInitialized) return []\n return augmentCategories(\n this.categories,\n this.globalStore.copyStore.copy.categories,\n this.dateRangeCategoryTotals,\n this.monthlyCategoryTotals,\n )\n }\n\n get detailedCategoriesWithTransactions(): DetailedCategoryWithTransactions[] {\n return getDetailedCategoryTransactions(\n this.detailedCategories,\n this.globalStore.transactionStore.sortedTransactions,\n )\n }\n\n get incomeCategories(): DetailedCategory[] {\n return this.detailedCategories.filter((c) => c.is_income)\n }\n\n get spendCategories(): DetailedCategory[] {\n return this.detailedCategories.filter(\n (c) => !c.is_income && !c.isTransfer && c.guid !== CategoryGuids.INVESTMENTS,\n )\n }\n\n get transferCategories(): DetailedCategory[] {\n return this.detailedCategories.filter((c) => c.isTransfer)\n }\n\n setCategories = (categories: Category[]) => {\n this.categories = categories\n this.categoriesLoading = false\n this.categoriesLoaded = true\n }\n\n setMonthlyCategoryTotals = (totals: MonthlyCategoryTotals[]) => {\n this.monthlyCategoryTotals = totals\n this.monthlyTotalsLoading = false\n this.monthlyTotalsLoaded = true\n }\n\n setDateRangeCategoryTotals = (totals: DateRangeCategoryTotals[]) => {\n this.dateRangeCategoryTotals = totals\n this.dateRangeTotalsLoading = false\n this.dateRangeTotalsLoaded = true\n }\n\n get trendsCategories(): DetailedCategory[] {\n return this.detailedCategories\n .filter((c) => c.totalAmount !== 0)\n .filter((c) => c.guid !== CategoryGuids.INVESTMENTS && c.guid !== CategoryGuids.TRANSFER)\n }\n\n addCategory = async (name: string, parentGuid: string) => {\n const category = { name, parent_guid: parentGuid } as Category\n\n try {\n await this.api.addCategory(category)\n await this.loadCategories()\n } catch (error) {\n console.error('Error occurred while adding category:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n }\n }\n\n loadCategories = async () => {\n if (this.categoriesLoading) return\n\n this.categoriesLoading = true\n try {\n const categories = await this.api.getCategories()\n this.setCategories(categories)\n } catch (error) {\n console.error('Error occurred while getting categories:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n runInAction(() => {\n this.categoriesLoading = false\n })\n }\n }\n\n loadDateRangeCategoryTotals = async (accounts: Account[], startDate: Date, endDate: Date) => {\n // Claim this request. Any request started later wins, so a date-range or\n // account change made while a request is in flight is no longer dropped.\n const requestId = ++this.dateRangeTotalsRequestId\n const isStale = () => requestId !== this.dateRangeTotalsRequestId\n\n runInAction(() => {\n this.dateRangeTotalsLoading = true\n })\n\n try {\n const totals = await this.api.getDateRangeCategoryTotals(\n getUnixTime(startDate),\n getUnixTime(endDate),\n accounts,\n )\n // A newer request superseded this one; its response is authoritative.\n // Leave the loading flag alone: the newest request still owns it.\n if (isStale()) return\n this.setDateRangeCategoryTotals(totals)\n } catch (error) {\n // Don't report deliberately superseded requests — rapid date scrubbing\n // would otherwise spam the error backend. (MEW-3910)\n if (isStale()) return\n console.error('Error occurred while getting date range category totals:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n this.setDateRangeCategoryTotals([])\n }\n }\n\n loadMonthlyCategoryTotals = async (\n accounts: Account[] = this.globalStore.globalUiStore.selectedAccounts,\n startDate?: Date,\n endDate?: Date,\n ) => {\n // See loadDateRangeCategoryTotals: newest request wins. (MEW-3910)\n const requestId = ++this.monthlyTotalsRequestId\n const isStale = () => requestId !== this.monthlyTotalsRequestId\n runInAction(() => {\n this.monthlyTotalsLoading = true\n })\n\n const start = getUnixTime(startOfMonth(startDate ?? subMonths(new Date(), 11)))\n const end = getUnixTime(endOfMonth(endDate ?? new Date()))\n\n try {\n const totals = await this.api.getMonthlyCategoryTotals(start, end, accounts)\n if (isStale()) return\n this.setMonthlyCategoryTotals(totals)\n } catch (error) {\n // Superseded requests are not reported. (MEW-3910)\n if (isStale()) return\n console.error('Error occurred while getting monthly category totals:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n // Setter clears monthlyTotalsLoading and marks loaded so the UI recovers\n // and retries aren't blocked. (MEW-3538)\n this.setMonthlyCategoryTotals([])\n }\n }\n\n reloadCategoryTotals = async (accounts: Account[], startDate?: Date, endDate?: Date) => {\n const start = startDate ?? subMonths(new Date(), 11)\n const end = endDate ?? endOfMonth(new Date())\n // Each loader claims its own token, so the pair does not invalidate itself.\n // No try/catch: both loaders handle and report their own errors and always\n // resolve, so nothing can reject here.\n await Promise.all([\n this.loadMonthlyCategoryTotals(accounts, start, end),\n this.loadDateRangeCategoryTotals(accounts, start, end),\n ])\n }\n\n removeCategory = async (guid: string) => {\n try {\n await this.api.removeCategory(guid)\n await this.loadCategories()\n } catch (error) {\n console.error('Error occurred while removing category:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n }\n }\n\n updateCategory = async (category: Category) => {\n try {\n await this.api.updateCategory(category)\n await this.loadCategories()\n } catch (error) {\n console.error('Error occurred while updating category:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n }\n }\n\n // TODO: Remove this after refactoring Trends components to use detailedCategories\n getCategoryName = (guid: string) => {\n const category = this.categories.find((c) => c.guid === guid)\n return category?.name ?? CategoryGuidToName[guid]\n }\n}\n\n// TODO: Move into CategoryStore\nclass UiStore {\n expandedGuid: string | null = null\n selectedGuid: string | null = null\n searchValue = ''\n showSelected = true\n shouldDisableDrawerScroll = false\n unselectable: string[] = []\n unselectableText = ''\n\n savedOnSelect: any // todo\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setExpandedGuid = (guid: string | null) => (this.expandedGuid = guid)\n\n setSelectedGuid = (guid: string | null) => (this.selectedGuid = guid)\n\n setSearchValue = (value: string) => (this.searchValue = value)\n\n setShouldDisableDrawerScroll = (shouldDisable: boolean) =>\n (this.shouldDisableDrawerScroll = shouldDisable)\n\n setShowSelected = (showSelected: boolean) => (this.showSelected = showSelected)\n\n setUnselectable = (unselectable: string[]) => (this.unselectable = unselectable)\n\n setUnselectableText = (text: string) => (this.unselectableText = text)\n\n onSelect = (guid: string) => this.savedOnSelect(guid)\n\n setOnSelect = (callback: any) => (this.savedOnSelect = callback)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CategoryStore.es.js","names":[],"sources":["../../../src/core/stores/CategoryStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\nimport { subMonths } from 'date-fns/subMonths'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { endOfMonth } from 'date-fns/endOfMonth'\n\nimport { CategoryGuids, CategoryGuidToName } from '../constants'\nimport { CategoryApi } from '../api'\nimport { toUnixUTC } from '../utils/DateUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nimport type {\n Account,\n Category,\n DetailedCategory,\n DetailedCategoryWithTransactions,\n DateRangeCategoryTotals,\n MonthlyCategoryTotals,\n} from '../types'\n\nimport { augmentCategories, getDetailedCategoryTransactions } from '../utils/CategoryUtil'\n\nexport class CategoryStore {\n globalStore: GlobalStore\n uiStore: UiStore\n api = new CategoryApi('/', '')\n\n categories: Category[] = []\n categoriesLoaded: boolean = false\n categoriesLoading: boolean = false\n dateRangeCategoryTotals: DateRangeCategoryTotals[] = []\n monthlyCategoryTotals: MonthlyCategoryTotals[] = []\n\n dateRangeTotalsLoaded = false\n dateRangeTotalsLoading = false\n monthlyTotalsLoaded = false\n monthlyTotalsLoading = false\n\n // Monotonic request tokens, one per totals endpoint. A newer request\n // supersedes an older in-flight one: the stale response is discarded rather\n // than the newer request being dropped. These loaders used to early-return\n // while a request was in flight, which silently swallowed date-range/account\n // changes made mid-flight. (MEW-3910)\n //\n // Deliberately per-endpoint rather than one shared counter: several callers\n // (BubbleBudgetsWidget, BubbleBudgetsMiniWidget) fire the two loaders\n // independently and concurrently, and a shared counter would make the second\n // call supersede — and silently drop — the first.\n //\n // Kept out of the observable graph — internal concurrency bookkeeping, not\n // renderable state.\n dateRangeTotalsRequestId = 0\n monthlyTotalsRequestId = 0\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new CategoryApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this, {\n dateRangeTotalsRequestId: false,\n monthlyTotalsRequestId: false,\n })\n }\n\n get detailedCategories(): DetailedCategory[] {\n if (!this.globalStore.isInitialized) return []\n return augmentCategories(\n this.categories,\n this.globalStore.copyStore.copy.categories,\n this.dateRangeCategoryTotals,\n this.monthlyCategoryTotals,\n )\n }\n\n get detailedCategoriesWithTransactions(): DetailedCategoryWithTransactions[] {\n return getDetailedCategoryTransactions(\n this.detailedCategories,\n this.globalStore.transactionStore.sortedTransactions,\n )\n }\n\n get incomeCategories(): DetailedCategory[] {\n return this.detailedCategories.filter((c) => c.is_income)\n }\n\n get spendCategories(): DetailedCategory[] {\n return this.detailedCategories.filter(\n (c) => !c.is_income && !c.isTransfer && c.guid !== CategoryGuids.INVESTMENTS,\n )\n }\n\n get transferCategories(): DetailedCategory[] {\n return this.detailedCategories.filter((c) => c.isTransfer)\n }\n\n setCategories = (categories: Category[]) => {\n this.categories = categories\n this.categoriesLoading = false\n this.categoriesLoaded = true\n }\n\n setMonthlyCategoryTotals = (totals: MonthlyCategoryTotals[]) => {\n this.monthlyCategoryTotals = totals\n this.monthlyTotalsLoading = false\n this.monthlyTotalsLoaded = true\n }\n\n setDateRangeCategoryTotals = (totals: DateRangeCategoryTotals[]) => {\n this.dateRangeCategoryTotals = totals\n this.dateRangeTotalsLoading = false\n this.dateRangeTotalsLoaded = true\n }\n\n get trendsCategories(): DetailedCategory[] {\n return this.detailedCategories\n .filter((c) => c.totalAmount !== 0)\n .filter((c) => c.guid !== CategoryGuids.INVESTMENTS && c.guid !== CategoryGuids.TRANSFER)\n }\n\n addCategory = async (name: string, parentGuid: string) => {\n const category = { name, parent_guid: parentGuid } as Category\n\n try {\n await this.api.addCategory(category)\n await this.loadCategories()\n } catch (error) {\n console.error('Error occurred while adding category:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n }\n }\n\n loadCategories = async () => {\n if (this.categoriesLoading) return\n\n this.categoriesLoading = true\n try {\n const categories = await this.api.getCategories()\n this.setCategories(categories)\n } catch (error) {\n console.error('Error occurred while getting categories:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n runInAction(() => {\n this.categoriesLoading = false\n })\n }\n }\n\n loadDateRangeCategoryTotals = async (accounts: Account[], startDate: Date, endDate: Date) => {\n // Claim this request. Any request started later wins, so a date-range or\n // account change made while a request is in flight is no longer dropped.\n const requestId = ++this.dateRangeTotalsRequestId\n const isStale = () => requestId !== this.dateRangeTotalsRequestId\n\n runInAction(() => {\n this.dateRangeTotalsLoading = true\n })\n\n try {\n // UTC-midnight boundaries so the window matches the absolute post dates the\n // API keys on; local Dates would shift it by the viewer's timezone offset.\n const totals = await this.api.getDateRangeCategoryTotals(\n toUnixUTC(startDate),\n toUnixUTC(endDate),\n accounts,\n )\n // A newer request superseded this one; its response is authoritative.\n // Leave the loading flag alone: the newest request still owns it.\n if (isStale()) return\n this.setDateRangeCategoryTotals(totals)\n } catch (error) {\n // Don't report deliberately superseded requests — rapid date scrubbing\n // would otherwise spam the error backend. (MEW-3910)\n if (isStale()) return\n console.error('Error occurred while getting date range category totals:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n this.setDateRangeCategoryTotals([])\n }\n }\n\n loadMonthlyCategoryTotals = async (\n accounts: Account[] = this.globalStore.globalUiStore.selectedAccounts,\n startDate?: Date,\n endDate?: Date,\n ) => {\n // See loadDateRangeCategoryTotals: newest request wins. (MEW-3910)\n const requestId = ++this.monthlyTotalsRequestId\n const isStale = () => requestId !== this.monthlyTotalsRequestId\n runInAction(() => {\n this.monthlyTotalsLoading = true\n })\n\n // UTC-midnight boundaries; see loadDateRangeCategoryTotals.\n const start = toUnixUTC(startOfMonth(startDate ?? subMonths(new Date(), 11)))\n const end = toUnixUTC(endOfMonth(endDate ?? new Date()))\n\n try {\n const totals = await this.api.getMonthlyCategoryTotals(start, end, accounts)\n if (isStale()) return\n this.setMonthlyCategoryTotals(totals)\n } catch (error) {\n // Superseded requests are not reported. (MEW-3910)\n if (isStale()) return\n console.error('Error occurred while getting monthly category totals:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n // Setter clears monthlyTotalsLoading and marks loaded so the UI recovers\n // and retries aren't blocked. (MEW-3538)\n this.setMonthlyCategoryTotals([])\n }\n }\n\n reloadCategoryTotals = async (accounts: Account[], startDate?: Date, endDate?: Date) => {\n const start = startDate ?? subMonths(new Date(), 11)\n const end = endDate ?? endOfMonth(new Date())\n // Each loader claims its own token, so the pair does not invalidate itself.\n // No try/catch: both loaders handle and report their own errors and always\n // resolve, so nothing can reject here.\n await Promise.all([\n this.loadMonthlyCategoryTotals(accounts, start, end),\n this.loadDateRangeCategoryTotals(accounts, start, end),\n ])\n }\n\n removeCategory = async (guid: string) => {\n try {\n await this.api.removeCategory(guid)\n await this.loadCategories()\n } catch (error) {\n console.error('Error occurred while removing category:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n }\n }\n\n updateCategory = async (category: Category) => {\n try {\n await this.api.updateCategory(category)\n await this.loadCategories()\n } catch (error) {\n console.error('Error occurred while updating category:', error)\n this.globalStore.captureException(error, { store: 'CategoryStore' })\n }\n }\n\n // TODO: Remove this after refactoring Trends components to use detailedCategories\n getCategoryName = (guid: string) => {\n const category = this.categories.find((c) => c.guid === guid)\n return category?.name ?? CategoryGuidToName[guid]\n }\n}\n\n// TODO: Move into CategoryStore\nclass UiStore {\n expandedGuid: string | null = null\n selectedGuid: string | null = null\n searchValue = ''\n showSelected = true\n shouldDisableDrawerScroll = false\n unselectable: string[] = []\n unselectableText = ''\n\n savedOnSelect: any // todo\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setExpandedGuid = (guid: string | null) => (this.expandedGuid = guid)\n\n setSelectedGuid = (guid: string | null) => (this.selectedGuid = guid)\n\n setSearchValue = (value: string) => (this.searchValue = value)\n\n setShouldDisableDrawerScroll = (shouldDisable: boolean) =>\n (this.shouldDisableDrawerScroll = shouldDisable)\n\n setShowSelected = (showSelected: boolean) => (this.showSelected = showSelected)\n\n setUnselectable = (unselectable: string[]) => (this.unselectable = unselectable)\n\n setUnselectableText = (text: string) => (this.unselectableText = text)\n\n onSelect = (guid: string) => this.savedOnSelect(guid)\n\n setOnSelect = (callback: any) => (this.savedOnSelect = callback)\n}\n"],"mappings":"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"}
@@ -3,8 +3,8 @@ import { augmentChartData as s, augmentSpendingFeeTransactions as i } from "../u
3
3
  import { format as c } from "date-fns/format";
4
4
  import { subMonths as h } from "date-fns/subMonths";
5
5
  import { makeAutoObservable as l, runInAction as r } from "mobx";
6
- import { getUnixTime as n } from "date-fns/getUnixTime";
7
6
  import { fromUnixTime as g } from "date-fns/fromUnixTime";
7
+ import { getUnixTime as n } from "date-fns/getUnixTime";
8
8
  var b = class {
9
9
  api = new o("/", "");
10
10
  augmentedChartData = [];
@@ -8,6 +8,7 @@ export declare const getNextQuarterlyDate: (date: Date) => Date;
8
8
  export declare const getNextBiQuarterlyDate: (date: Date) => Date;
9
9
  export declare const getNextYearlyDate: (date: Date) => Date;
10
10
  export declare const fromUnixUTC: (utcTime: number) => Date;
11
+ export declare const toUnixUTC: (date: Date) => number;
11
12
  export declare const fromUnixToDayOfWeekAndDate: (date: number) => string;
12
13
  export declare const fromUnixUTCToDayOfWeekAndDate: (date: number) => string;
13
14
  export declare const fromTimestampToMonthYear: (timestamp?: number) => string;
@@ -1,26 +1,26 @@
1
- import { DATE_FORMATS_INTL as s, formatDate as y } from "../constants/DateFormats.es.js";
1
+ import { DATE_FORMATS_INTL as g, formatDate as x } from "../constants/DateFormats.es.js";
2
2
  import { addMonths as i } from "date-fns/addMonths";
3
3
  import { endOfMonth as h } from "date-fns/endOfMonth";
4
4
  import { isBefore as n } from "date-fns/isBefore";
5
5
  import { startOfToday as a } from "date-fns/startOfToday";
6
- import { addYears as u } from "date-fns/addYears";
6
+ import { addYears as M } from "date-fns/addYears";
7
+ import { addQuarters as s } from "date-fns/addQuarters";
8
+ import { addWeeks as y } from "date-fns/addWeeks";
9
+ import { getDay as d } from "date-fns/getDay";
10
+ import { nextDay as v } from "date-fns/nextDay";
11
+ import { setDate as u } from "date-fns/setDate";
7
12
  import { fromUnixTime as T } from "date-fns/fromUnixTime";
8
- import { addQuarters as x } from "date-fns/addQuarters";
9
- import { addWeeks as d } from "date-fns/addWeeks";
10
- import { nextDay as p } from "date-fns/nextDay";
11
- import { setDate as g } from "date-fns/setDate";
12
- import { getDay as v } from "date-fns/getDay";
13
- var B = (e) => {
14
- const t = v(e);
15
- let r = p(e, t);
16
- for (; n(r, a()); ) r = d(r, 1);
13
+ var B = (t) => {
14
+ const e = d(t);
15
+ let r = v(t, e);
16
+ for (; n(r, a()); ) r = y(r, 1);
17
17
  return r;
18
- }, H = (e) => {
19
- let t = e;
20
- for (; n(t, a()); ) t = d(t, 2);
21
- return t;
22
- }, M = (e, t) => {
23
- const r = a(), [o, m] = [e, t].sort((f, l) => f - l), D = (f, l) => l >= 28 ? h(f) : g(f, l);
18
+ }, H = (t) => {
19
+ let e = t;
20
+ for (; n(e, a()); ) e = y(e, 2);
21
+ return e;
22
+ }, p = (t, e) => {
23
+ const r = a(), [o, m] = [t, e].sort((f, l) => f - l), D = (f, l) => l >= 28 ? h(f) : u(f, l);
24
24
  return [
25
25
  D(r, o),
26
26
  D(r, m),
@@ -29,43 +29,44 @@ var B = (e) => {
29
29
  D(i(r, 2), o),
30
30
  D(i(r, 2), m)
31
31
  ];
32
- }, Q = (e, t) => {
33
- const r = a(), o = M(e, t);
32
+ }, Q = (t, e) => {
33
+ const r = a(), o = p(t, e);
34
34
  return o.find((m) => !n(m, r)) ?? o[o.length - 1];
35
- }, K = (e) => {
36
- let t = g(a(), e.getDate());
37
- for (; n(t, a()); ) t = i(t, 1);
38
- return t;
39
- }, R = (e) => {
40
- let t = e;
41
- for (; n(t, a()); ) t = i(t, 2);
42
- return t;
43
- }, I = (e) => {
44
- let t = x(e, 1);
45
- for (; n(t, a()); ) t = x(t, 1);
46
- return t;
47
- }, L = (e) => {
48
- let t = e;
49
- for (; n(t, a()); ) t = x(t, 2);
50
- return t;
51
- }, S = (e) => u(e, 1), N = (e) => {
52
- const t = T(e);
53
- return new Date(t.getUTCFullYear(), t.getUTCMonth(), t.getUTCDate());
54
- }, b = (e) => y(T(e), s.DAY_OF_WEEK_MONTH_DAY), j = (e) => y(N(e), s.DAY_OF_WEEK_MONTH_DAY), q = (e) => e ? y(T(e), s.MONTH_YEAR) : "";
35
+ }, K = (t) => {
36
+ let e = u(a(), t.getDate());
37
+ for (; n(e, a()); ) e = i(e, 1);
38
+ return e;
39
+ }, R = (t) => {
40
+ let e = t;
41
+ for (; n(e, a()); ) e = i(e, 2);
42
+ return e;
43
+ }, S = (t) => {
44
+ let e = s(t, 1);
45
+ for (; n(e, a()); ) e = s(e, 1);
46
+ return e;
47
+ }, I = (t) => {
48
+ let e = t;
49
+ for (; n(e, a()); ) e = s(e, 2);
50
+ return e;
51
+ }, L = (t) => M(t, 1), c = (t) => {
52
+ const e = T(t);
53
+ return new Date(e.getUTCFullYear(), e.getUTCMonth(), e.getUTCDate());
54
+ }, b = (t) => Math.floor(Date.UTC(t.getFullYear(), t.getMonth(), t.getDate(), t.getHours(), t.getMinutes(), t.getSeconds()) / 1e3), j = (t) => x(T(t), g.DAY_OF_WEEK_MONTH_DAY), q = (t) => x(c(t), g.DAY_OF_WEEK_MONTH_DAY), z = (t) => t ? x(T(t), g.MONTH_YEAR) : "";
55
55
  export {
56
- q as fromTimestampToMonthYear,
57
- b as fromUnixToDayOfWeekAndDate,
58
- N as fromUnixUTC,
59
- j as fromUnixUTCToDayOfWeekAndDate,
56
+ z as fromTimestampToMonthYear,
57
+ j as fromUnixToDayOfWeekAndDate,
58
+ c as fromUnixUTC,
59
+ q as fromUnixUTCToDayOfWeekAndDate,
60
60
  R as getNextBiMonthlyDate,
61
- L as getNextBiQuarterlyDate,
61
+ I as getNextBiQuarterlyDate,
62
62
  H as getNextBiWeeklyDate,
63
63
  K as getNextMonthlyDate,
64
- I as getNextQuarterlyDate,
64
+ S as getNextQuarterlyDate,
65
65
  Q as getNextTwiceMonthlyDate,
66
66
  B as getNextWeeklyDate,
67
- S as getNextYearlyDate,
68
- M as getTwiceMonthlyDates
67
+ L as getNextYearlyDate,
68
+ p as getTwiceMonthlyDates,
69
+ b as toUnixUTC
69
70
  };
70
71
 
71
72
  //# sourceMappingURL=DateUtil.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateUtil.es.js","names":[],"sources":["../../../src/core/utils/DateUtil.ts"],"sourcesContent":["import { addMonths } from 'date-fns/addMonths'\nimport { addQuarters } from 'date-fns/addQuarters'\nimport { addWeeks } from 'date-fns/addWeeks'\nimport { addYears } from 'date-fns/addYears'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { getDay } from 'date-fns/getDay'\nimport { isBefore } from 'date-fns/isBefore'\nimport { nextDay } from 'date-fns/nextDay'\nimport { setDate } from 'date-fns/setDate'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { fromUnixTime } from 'date-fns/fromUnixTime'\nimport { type Day } from 'date-fns'\n\nimport { DATE_FORMATS_INTL, formatDate } from '../constants'\n\nexport const getNextWeeklyDate = (date: Date): Date => {\n const dayOfWeek = getDay(date)\n let nextDate = nextDay(date, dayOfWeek as Day)\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addWeeks(nextDate, 1)\n }\n return nextDate\n}\n\nexport const getNextBiWeeklyDate = (date: Date): Date => {\n let nextDate = date\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addWeeks(nextDate, 2)\n }\n return nextDate\n}\n\nexport const getTwiceMonthlyDates = (day1: number, day2: number): Date[] => {\n const today = startOfToday()\n const [firstDay, secondDay] = [day1, day2].sort((a, b) => a - b)\n const makeDateForDay = (month: Date, day: number) =>\n day >= 28 ? endOfMonth(month) : setDate(month, day)\n\n return [\n makeDateForDay(today, firstDay),\n makeDateForDay(today, secondDay),\n makeDateForDay(addMonths(today, 1), firstDay),\n makeDateForDay(addMonths(today, 1), secondDay),\n makeDateForDay(addMonths(today, 2), firstDay),\n makeDateForDay(addMonths(today, 2), secondDay),\n ]\n}\n\nexport const getNextTwiceMonthlyDate = (day1: number, day2: number): Date => {\n const today = startOfToday()\n const candidates = getTwiceMonthlyDates(day1, day2)\n return candidates.find((c) => !isBefore(c, today)) ?? candidates[candidates.length - 1]\n}\n\nexport const getNextMonthlyDate = (date: Date): Date => {\n let nextDate = setDate(startOfToday(), date.getDate())\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addMonths(nextDate, 1)\n }\n return nextDate\n}\n\nexport const getNextBiMonthlyDate = (date: Date): Date => {\n let nextDate = date\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addMonths(nextDate, 2)\n }\n return nextDate\n}\n\nexport const getNextQuarterlyDate = (date: Date): Date => {\n let nextDate = addQuarters(date, 1)\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addQuarters(nextDate, 1)\n }\n return nextDate\n}\n\nexport const getNextBiQuarterlyDate = (date: Date): Date => {\n let nextDate = date\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addQuarters(nextDate, 2)\n }\n return nextDate\n}\n\nexport const getNextYearlyDate = (date: Date): Date => {\n return addYears(date, 1)\n}\n\nexport const fromUnixUTC = (utcTime: number) => {\n const date = fromUnixTime(utcTime)\n return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())\n}\n\nexport const fromUnixToDayOfWeekAndDate = (date: number) =>\n formatDate(fromUnixTime(date), DATE_FORMATS_INTL.DAY_OF_WEEK_MONTH_DAY)\n\n// UTC variant for post dates, which are absolute calendar dates that must not\n// shift across the day boundary when localized.\nexport const fromUnixUTCToDayOfWeekAndDate = (date: number) =>\n formatDate(fromUnixUTC(date), DATE_FORMATS_INTL.DAY_OF_WEEK_MONTH_DAY)\n\nexport const fromTimestampToMonthYear = (timestamp?: number) =>\n timestamp ? formatDate(fromUnixTime(timestamp), DATE_FORMATS_INTL.MONTH_YEAR) : ''\n"],"mappings":";;;;;;;;;;;;AAeA,IAAa,IAAA,CAAqB,MAAqB;AACrD,QAAM,IAAY,EAAO,CAAI;AAC7B,MAAI,IAAW,EAAQ,GAAM,CAAgB;AAC7C,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAS,GAAU,CAAC;AAEjC,SAAO;AACT,GAEa,IAAA,CAAuB,MAAqB;AACvD,MAAI,IAAW;AACf,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAS,GAAU,CAAC;AAEjC,SAAO;AACT,GAEa,IAAA,CAAwB,GAAc,MAAyB;AAC1E,QAAM,IAAQ,EAAa,GACrB,CAAC,GAAU,CAAA,IAAa,CAAC,GAAM,CAAI,EAAE,KAAA,CAAM,GAAG,MAAM,IAAI,CAAC,GACzD,IAAA,CAAkB,GAAa,MACnC,KAAO,KAAK,EAAW,CAAK,IAAI,EAAQ,GAAO,CAAG;AAEpD,SAAO;AAAA,IACL,EAAe,GAAO,CAAQ;AAAA,IAC9B,EAAe,GAAO,CAAS;AAAA,IAC/B,EAAe,EAAU,GAAO,CAAC,GAAG,CAAQ;AAAA,IAC5C,EAAe,EAAU,GAAO,CAAC,GAAG,CAAS;AAAA,IAC7C,EAAe,EAAU,GAAO,CAAC,GAAG,CAAQ;AAAA,IAC5C,EAAe,EAAU,GAAO,CAAC,GAAG,CAAS;AAAA,EAC/C;AACF,GAEa,IAAA,CAA2B,GAAc,MAAuB;AAC3E,QAAM,IAAQ,EAAa,GACrB,IAAa,EAAqB,GAAM,CAAI;AAClD,SAAO,EAAW,KAAA,CAAM,MAAM,CAAC,EAAS,GAAG,CAAK,CAAC,KAAK,EAAW,EAAW,SAAS,CAAA;AACvF,GAEa,IAAA,CAAsB,MAAqB;AACtD,MAAI,IAAW,EAAQ,EAAa,GAAG,EAAK,QAAQ,CAAC;AACrD,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAU,GAAU,CAAC;AAElC,SAAO;AACT,GAEa,IAAA,CAAwB,MAAqB;AACxD,MAAI,IAAW;AACf,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAU,GAAU,CAAC;AAElC,SAAO;AACT,GAEa,IAAA,CAAwB,MAAqB;AACxD,MAAI,IAAW,EAAY,GAAM,CAAC;AAClC,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAY,GAAU,CAAC;AAEpC,SAAO;AACT,GAEa,IAAA,CAA0B,MAAqB;AAC1D,MAAI,IAAW;AACf,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAY,GAAU,CAAC;AAEpC,SAAO;AACT,GAEa,IAAA,CAAqB,MACzB,EAAS,GAAM,CAAC,GAGZ,IAAA,CAAe,MAAoB;AAC9C,QAAM,IAAO,EAAa,CAAO;AACjC,SAAO,IAAI,KAAK,EAAK,eAAe,GAAG,EAAK,YAAY,GAAG,EAAK,WAAW,CAAC;AAC9E,GAEa,IAAA,CAA8B,MACzC,EAAW,EAAa,CAAI,GAAG,EAAkB,qBAAqB,GAI3D,IAAA,CAAiC,MAC5C,EAAW,EAAY,CAAI,GAAG,EAAkB,qBAAqB,GAE1D,IAAA,CAA4B,MACvC,IAAY,EAAW,EAAa,CAAS,GAAG,EAAkB,UAAU,IAAI"}
1
+ {"version":3,"file":"DateUtil.es.js","names":[],"sources":["../../../src/core/utils/DateUtil.ts"],"sourcesContent":["import { addMonths } from 'date-fns/addMonths'\nimport { addQuarters } from 'date-fns/addQuarters'\nimport { addWeeks } from 'date-fns/addWeeks'\nimport { addYears } from 'date-fns/addYears'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { getDay } from 'date-fns/getDay'\nimport { isBefore } from 'date-fns/isBefore'\nimport { nextDay } from 'date-fns/nextDay'\nimport { setDate } from 'date-fns/setDate'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { fromUnixTime } from 'date-fns/fromUnixTime'\nimport { type Day } from 'date-fns'\n\nimport { DATE_FORMATS_INTL, formatDate } from '../constants'\n\nexport const getNextWeeklyDate = (date: Date): Date => {\n const dayOfWeek = getDay(date)\n let nextDate = nextDay(date, dayOfWeek as Day)\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addWeeks(nextDate, 1)\n }\n return nextDate\n}\n\nexport const getNextBiWeeklyDate = (date: Date): Date => {\n let nextDate = date\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addWeeks(nextDate, 2)\n }\n return nextDate\n}\n\nexport const getTwiceMonthlyDates = (day1: number, day2: number): Date[] => {\n const today = startOfToday()\n const [firstDay, secondDay] = [day1, day2].sort((a, b) => a - b)\n const makeDateForDay = (month: Date, day: number) =>\n day >= 28 ? endOfMonth(month) : setDate(month, day)\n\n return [\n makeDateForDay(today, firstDay),\n makeDateForDay(today, secondDay),\n makeDateForDay(addMonths(today, 1), firstDay),\n makeDateForDay(addMonths(today, 1), secondDay),\n makeDateForDay(addMonths(today, 2), firstDay),\n makeDateForDay(addMonths(today, 2), secondDay),\n ]\n}\n\nexport const getNextTwiceMonthlyDate = (day1: number, day2: number): Date => {\n const today = startOfToday()\n const candidates = getTwiceMonthlyDates(day1, day2)\n return candidates.find((c) => !isBefore(c, today)) ?? candidates[candidates.length - 1]\n}\n\nexport const getNextMonthlyDate = (date: Date): Date => {\n let nextDate = setDate(startOfToday(), date.getDate())\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addMonths(nextDate, 1)\n }\n return nextDate\n}\n\nexport const getNextBiMonthlyDate = (date: Date): Date => {\n let nextDate = date\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addMonths(nextDate, 2)\n }\n return nextDate\n}\n\nexport const getNextQuarterlyDate = (date: Date): Date => {\n let nextDate = addQuarters(date, 1)\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addQuarters(nextDate, 1)\n }\n return nextDate\n}\n\nexport const getNextBiQuarterlyDate = (date: Date): Date => {\n let nextDate = date\n while (isBefore(nextDate, startOfToday())) {\n nextDate = addQuarters(nextDate, 2)\n }\n return nextDate\n}\n\nexport const getNextYearlyDate = (date: Date): Date => {\n return addYears(date, 1)\n}\n\nexport const fromUnixUTC = (utcTime: number) => {\n const date = fromUnixTime(utcTime)\n return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())\n}\n\n// Inverse of fromUnixUTC: emits unix seconds for the Date's wall-clock time read\n// at UTC, so a local-midnight boundary serializes to UTC midnight instead of\n// being shifted by the viewer's timezone offset.\nexport const toUnixUTC = (date: Date) =>\n Math.floor(\n Date.UTC(\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n ) / 1000,\n )\n\nexport const fromUnixToDayOfWeekAndDate = (date: number) =>\n formatDate(fromUnixTime(date), DATE_FORMATS_INTL.DAY_OF_WEEK_MONTH_DAY)\n\n// UTC variant for post dates, which are absolute calendar dates that must not\n// shift across the day boundary when localized.\nexport const fromUnixUTCToDayOfWeekAndDate = (date: number) =>\n formatDate(fromUnixUTC(date), DATE_FORMATS_INTL.DAY_OF_WEEK_MONTH_DAY)\n\nexport const fromTimestampToMonthYear = (timestamp?: number) =>\n timestamp ? formatDate(fromUnixTime(timestamp), DATE_FORMATS_INTL.MONTH_YEAR) : ''\n"],"mappings":";;;;;;;;;;;;AAeA,IAAa,IAAA,CAAqB,MAAqB;AACrD,QAAM,IAAY,EAAO,CAAI;AAC7B,MAAI,IAAW,EAAQ,GAAM,CAAgB;AAC7C,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAS,GAAU,CAAC;AAEjC,SAAO;AACT,GAEa,IAAA,CAAuB,MAAqB;AACvD,MAAI,IAAW;AACf,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAS,GAAU,CAAC;AAEjC,SAAO;AACT,GAEa,IAAA,CAAwB,GAAc,MAAyB;AAC1E,QAAM,IAAQ,EAAa,GACrB,CAAC,GAAU,CAAA,IAAa,CAAC,GAAM,CAAI,EAAE,KAAA,CAAM,GAAG,MAAM,IAAI,CAAC,GACzD,IAAA,CAAkB,GAAa,MACnC,KAAO,KAAK,EAAW,CAAK,IAAI,EAAQ,GAAO,CAAG;AAEpD,SAAO;AAAA,IACL,EAAe,GAAO,CAAQ;AAAA,IAC9B,EAAe,GAAO,CAAS;AAAA,IAC/B,EAAe,EAAU,GAAO,CAAC,GAAG,CAAQ;AAAA,IAC5C,EAAe,EAAU,GAAO,CAAC,GAAG,CAAS;AAAA,IAC7C,EAAe,EAAU,GAAO,CAAC,GAAG,CAAQ;AAAA,IAC5C,EAAe,EAAU,GAAO,CAAC,GAAG,CAAS;AAAA,EAC/C;AACF,GAEa,IAAA,CAA2B,GAAc,MAAuB;AAC3E,QAAM,IAAQ,EAAa,GACrB,IAAa,EAAqB,GAAM,CAAI;AAClD,SAAO,EAAW,KAAA,CAAM,MAAM,CAAC,EAAS,GAAG,CAAK,CAAC,KAAK,EAAW,EAAW,SAAS,CAAA;AACvF,GAEa,IAAA,CAAsB,MAAqB;AACtD,MAAI,IAAW,EAAQ,EAAa,GAAG,EAAK,QAAQ,CAAC;AACrD,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAU,GAAU,CAAC;AAElC,SAAO;AACT,GAEa,IAAA,CAAwB,MAAqB;AACxD,MAAI,IAAW;AACf,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAU,GAAU,CAAC;AAElC,SAAO;AACT,GAEa,IAAA,CAAwB,MAAqB;AACxD,MAAI,IAAW,EAAY,GAAM,CAAC;AAClC,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAY,GAAU,CAAC;AAEpC,SAAO;AACT,GAEa,IAAA,CAA0B,MAAqB;AAC1D,MAAI,IAAW;AACf,SAAO,EAAS,GAAU,EAAa,CAAC,IACtC,CAAA,IAAW,EAAY,GAAU,CAAC;AAEpC,SAAO;AACT,GAEa,IAAA,CAAqB,MACzB,EAAS,GAAM,CAAC,GAGZ,IAAA,CAAe,MAAoB;AAC9C,QAAM,IAAO,EAAa,CAAO;AACjC,SAAO,IAAI,KAAK,EAAK,eAAe,GAAG,EAAK,YAAY,GAAG,EAAK,WAAW,CAAC;AAC9E,GAKa,IAAA,CAAa,MACxB,KAAK,MACH,KAAK,IACH,EAAK,YAAY,GACjB,EAAK,SAAS,GACd,EAAK,QAAQ,GACb,EAAK,SAAS,GACd,EAAK,WAAW,GAChB,EAAK,WAAW,CAClB,IAAI,GACN,GAEW,IAAA,CAA8B,MACzC,EAAW,EAAa,CAAI,GAAG,EAAkB,qBAAqB,GAI3D,IAAA,CAAiC,MAC5C,EAAW,EAAY,CAAI,GAAG,EAAkB,qBAAqB,GAE1D,IAAA,CAA4B,MACvC,IAAY,EAAW,EAAa,CAAS,GAAG,EAAkB,UAAU,IAAI"}
@@ -2,9 +2,9 @@ import { AccountType as C } from "../types/Account.es.js";
2
2
  import { DebtPriority as b } from "../constants/Debts.es.js";
3
3
  import { addMonths as E } from "date-fns/addMonths";
4
4
  import { startOfMonth as x } from "date-fns/startOfMonth";
5
- import { getUnixTime as w } from "date-fns/getUnixTime";
6
- import { getDate as T } from "date-fns/getDate";
7
5
  import { fromUnixTime as d } from "date-fns/fromUnixTime";
6
+ import { getDate as w } from "date-fns/getDate";
7
+ import { getUnixTime as T } from "date-fns/getUnixTime";
8
8
  var F = { unnamed_label: "Unnamed Debt" }, G = (a, n, t = 0) => {
9
9
  const o = a.map((s) => ({ ...s }));
10
10
  S(o, n);
@@ -63,10 +63,10 @@ function P(a, n) {
63
63
  guid: a.guid
64
64
  };
65
65
  if (n) {
66
- const o = n.payment_due_at ? T(d(n.payment_due_at)) : 1, i = x(/* @__PURE__ */ new Date()).setDate(o);
66
+ const o = n.payment_due_at ? w(d(n.payment_due_at)) : 1, i = x(/* @__PURE__ */ new Date()).setDate(o);
67
67
  t.balance = Math.abs(n.amount - n.current_amount), t.interest_rate = n.interest_rate, t.is_paid_off = n.is_complete, t.monthly_payment = n.monthly_payment, t.name = n.name, t.original_balance = n.initial_amount, t.payment_due_date = i;
68
68
  } else {
69
- const o = a.payment_due_at ? T(d(a.payment_due_at)) : 1, i = x(/* @__PURE__ */ new Date()).setDate(o), e = a.balance ?? 0, r = a.minimum_payment ?? void 0, m = a.interest_rate ?? void 0;
69
+ const o = a.payment_due_at ? w(d(a.payment_due_at)) : 1, i = x(/* @__PURE__ */ new Date()).setDate(o), e = a.balance ?? 0, r = a.minimum_payment ?? void 0, m = a.interest_rate ?? void 0;
70
70
  t.balance = Math.max(e, 0), t.interest_rate = m, t.is_paid_off = e === 0, t.monthly_payment = r, t.name = a?.name ?? F.unnamed_label, t.original_balance = a.original_balance, t.payment_due_date = i;
71
71
  }
72
72
  return t.is_impossible = !1, t.priority = void 0, t.projected_payoff_date = void 0, t;
@@ -114,14 +114,14 @@ var I = (a) => (a[a.length - 1] || {}).timestamp, S = (a, n) => {
114
114
  interest: t,
115
115
  payment: p,
116
116
  principal: p,
117
- timestamp: w(E(d(i), m + 1))
117
+ timestamp: T(E(d(i), m + 1))
118
118
  });
119
119
  }
120
120
  return e;
121
121
  }
122
122
  const r = t / 1200;
123
123
  for (let m = 0; m < a; m++) {
124
- const s = w(E(d(i), m + 1)), c = Math.pow(1 + r, m), p = n * c - o * ((c - 1) / r), _ = Math.pow(1 + r, m + 1), l = n * _ - o * ((_ - 1) / r), y = o + Math.min(l, 0), u = p * r;
124
+ const s = T(E(d(i), m + 1)), c = Math.pow(1 + r, m), p = n * c - o * ((c - 1) / r), _ = Math.pow(1 + r, m + 1), l = n * _ - o * ((_ - 1) / r), y = o + Math.min(l, 0), u = p * r;
125
125
  e.push({
126
126
  balance: Math.max(0, l),
127
127
  interest: u,
@@ -3,8 +3,8 @@ import { DATE_FORMATS_INTL as b, formatDate as E } from "../constants/DateFormat
3
3
  import { MetaType as r, TrackType as o } from "../types/Goal.es.js";
4
4
  import { formatPercentage as u } from "./NumberFormatting.es.js";
5
5
  import { addYears as d } from "date-fns/addYears";
6
- import { getUnixTime as R } from "date-fns/getUnixTime";
7
6
  import { fromUnixTime as m } from "date-fns/fromUnixTime";
7
+ import { getUnixTime as R } from "date-fns/getUnixTime";
8
8
  function O(e, t) {
9
9
  const i = t.track_type === o.DEBT_TRACK ? t.initial_amount : t.amount;
10
10
  let a = t.current_amount / i;
@@ -13,16 +13,16 @@ import { addYears as A } from "date-fns/addYears";
13
13
  import { subDays as Y } from "date-fns/subDays";
14
14
  import { subYears as J } from "date-fns/subYears";
15
15
  import { differenceInDays as V } from "date-fns/differenceInDays";
16
- import { getUnixTime as f } from "date-fns/getUnixTime";
17
- import { fromUnixTime as X } from "date-fns/fromUnixTime";
18
- import { isAfter as l } from "date-fns/isAfter";
19
16
  import { addQuarters as G } from "date-fns/addQuarters";
20
17
  import { addWeeks as k } from "date-fns/addWeeks";
18
+ import { nextDay as M } from "date-fns/nextDay";
19
+ import { setDate as E } from "date-fns/setDate";
20
+ import { fromUnixTime as X } from "date-fns/fromUnixTime";
21
+ import { getUnixTime as f } from "date-fns/getUnixTime";
22
+ import { isAfter as l } from "date-fns/isAfter";
21
23
  import { formatISO as Z } from "date-fns/formatISO";
22
24
  import { lastDayOfMonth as T } from "date-fns/lastDayOfMonth";
23
- import { nextDay as M } from "date-fns/nextDay";
24
25
  import { parseISO as S } from "date-fns/parseISO";
25
- import { setDate as E } from "date-fns/setDate";
26
26
  import { setDay as ee } from "date-fns/setDay";
27
27
  import { setDayOfYear as B } from "date-fns/setDayOfYear";
28
28
  import { subQuarters as I } from "date-fns/subQuarters";
@@ -8,8 +8,8 @@ import { format as O } from "date-fns/format";
8
8
  import { startOfMonth as S } from "date-fns/startOfMonth";
9
9
  import { startOfToday as D } from "date-fns/startOfToday";
10
10
  import { endOfToday as M } from "date-fns/endOfToday";
11
- import { getUnixTime as _ } from "date-fns/getUnixTime";
12
11
  import { fromUnixTime as T } from "date-fns/fromUnixTime";
12
+ import { getUnixTime as _ } from "date-fns/getUnixTime";
13
13
  var K = (r, t, n, a = []) => {
14
14
  const s = t.reduce((o, e) => ({
15
15
  ...o,
@@ -4,8 +4,8 @@ import { ListItemAction as v } from "../../../common/components/ListItemAction.e
4
4
  import i from "react";
5
5
  import { observer as A } from "mobx-react-lite";
6
6
  import { jsx as o } from "react/jsx-runtime";
7
- import { getUnixTime as T } from "date-fns/getUnixTime";
8
7
  import { fromUnixTime as s } from "date-fns/fromUnixTime";
8
+ import { getUnixTime as T } from "date-fns/getUnixTime";
9
9
  import { AdapterDateFns as x } from "@mui/x-date-pickers/AdapterDateFnsV3";
10
10
  import { DatePicker as D } from "@mui/x-date-pickers";
11
11
  import { LocalizationProvider as g } from "@mui/x-date-pickers/LocalizationProvider";
@@ -10,8 +10,8 @@ import { MerchantLogo as P, Text as a } from "@mxenabled/mxui";
10
10
  import { Cancel as U, CheckCircle as B, Icon as Y } from "@mxenabled/mx-icons";
11
11
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
12
12
  import F from "@mui/material/IconButton";
13
- import { getUnixTime as H } from "date-fns/getUnixTime";
14
- import { fromUnixTime as W } from "date-fns/fromUnixTime";
13
+ import { fromUnixTime as H } from "date-fns/fromUnixTime";
14
+ import { getUnixTime as W } from "date-fns/getUnixTime";
15
15
  import $ from "@mui/material/Divider";
16
16
  import K from "@mui/material/List";
17
17
  import V from "@mui/material/ListItemText";
@@ -33,7 +33,7 @@ var X = (d, u) => {
33
33
  key: `missed-${e.expectedDate.getTime()}`,
34
34
  name: e.name,
35
35
  amount: e.amount,
36
- date: H(e.expectedDate),
36
+ date: W(e.expectedDate),
37
37
  merchantGuid: e.merchantGuid,
38
38
  categoryGuid: e.categoryGuid,
39
39
  category: "",
@@ -88,7 +88,7 @@ var X = (d, u) => {
88
88
  justifyContent: "space-between",
89
89
  children: [/* @__PURE__ */ r(a, {
90
90
  variant: "caption",
91
- children: E(W(t.date), A.MONTH_DAY_YEAR)
91
+ children: E(H(t.date), A.MONTH_DAY_YEAR)
92
92
  }), /* @__PURE__ */ i(l, {
93
93
  alignItems: "center",
94
94
  direction: "row",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mx-cartographer/experiences",
3
- "version": "9.3.0",
3
+ "version": "9.3.1",
4
4
  "description": "Library containing experience widgets",
5
5
  "author": "MX",
6
6
  "license": "MIT",