@mx-cartographer/experiences 9.6.9 → 9.6.10
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 +4 -0
- package/dist/core/stores/AccountStore.d.ts +1 -0
- package/dist/core/stores/AccountStore.es.js +47 -42
- package/dist/core/stores/AccountStore.es.js.map +1 -1
- package/dist/core/stores/AppDataStore.d.ts +1 -0
- package/dist/core/stores/AppDataStore.es.js +15 -11
- package/dist/core/stores/AppDataStore.es.js.map +1 -1
- package/dist/core/stores/BeatStore.d.ts +1 -0
- package/dist/core/stores/BeatStore.es.js +10 -6
- package/dist/core/stores/BeatStore.es.js.map +1 -1
- package/dist/core/stores/BudgetsStore.d.ts +1 -0
- package/dist/core/stores/BudgetsStore.es.js +37 -35
- package/dist/core/stores/BudgetsStore.es.js.map +1 -1
- package/dist/core/stores/CategoryStore.d.ts +1 -0
- package/dist/core/stores/CategoryStore.es.js +36 -32
- package/dist/core/stores/CategoryStore.es.js.map +1 -1
- package/dist/core/stores/GlobalCopyStore.d.ts +1 -0
- package/dist/core/stores/GlobalCopyStore.es.js +17 -13
- package/dist/core/stores/GlobalCopyStore.es.js.map +1 -1
- package/dist/core/stores/HoldingStore.d.ts +1 -0
- package/dist/core/stores/HoldingStore.es.js +6 -2
- package/dist/core/stores/HoldingStore.es.js.map +1 -1
- package/dist/core/stores/TransactionStore.d.ts +1 -0
- package/dist/core/stores/TransactionStore.es.js +71 -67
- package/dist/core/stores/TransactionStore.es.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoldingStore.es.js","names":[],"sources":["../../../src/core/stores/HoldingStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { HoldingApi } from '../api'\nimport { AnalysisType } from '../constants/Investments'\nimport { type Holding } from '../types'\nimport {\n analysisChartData,\n analysisDetailsData,\n holdingHasAllocationData,\n holdingHasStyleData,\n mapDataToPercentageGrid,\n} from '../utils/InvestmentUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class HoldingStore {\n analysisType: AnalysisType = AnalysisType.Stocks\n api = new HoldingApi('/', '')\n holdings: Holding[] = []\n holdingsLoaded = false\n globalStore: GlobalStore\n showConnectionsWidget = false\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new HoldingApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n get analysisChartData() {\n return mapDataToPercentageGrid(analysisChartData(this.visibleHoldings), this.analysisType)\n }\n\n get analysisDetails() {\n return analysisDetailsData(this.visibleHoldings)[this.analysisType] || {}\n }\n\n get visibleHoldings() {\n return this.holdings.filter((holding) =>\n this.globalStore.globalUiStore.selectedAccountGuids.includes(holding.account_guid),\n )\n }\n\n // Cash counts because a cash balance renders as a synthetic donut slice.\n get hasAllocationData() {\n if (this.visibleHoldings.some(holdingHasAllocationData)) return true\n\n return this.selectedInvestmentAccounts.some((account) => (account.cash_balance ?? 0) > 0)\n }\n\n get hasAnalysisData() {\n return this.visibleHoldings.some(holdingHasStyleData)\n }\n\n get selectedInvestmentAccounts() {\n const { selectedAccountGuids } = this.globalStore.globalUiStore\n return this.globalStore.accountStore.visibleInvestmentAccounts.filter((account) =>\n selectedAccountGuids.includes(account.guid),\n )\n }\n\n setHoldings = (holdings: Holding[]) => {\n this.holdings = holdings\n this.holdingsLoaded = true\n }\n\n setShowConnectionsWidget = (value: boolean) => {\n this.showConnectionsWidget = value\n }\n\n loadHoldings = async () => {\n try {\n const holdings = await this.api.getHoldings()\n this.setHoldings(holdings)\n } catch (error) {\n
|
|
1
|
+
{"version":3,"file":"HoldingStore.es.js","names":[],"sources":["../../../src/core/stores/HoldingStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\n\nimport { HoldingApi } from '../api'\nimport { AnalysisType } from '../constants/Investments'\nimport { type Holding } from '../types'\nimport {\n analysisChartData,\n analysisDetailsData,\n holdingHasAllocationData,\n holdingHasStyleData,\n mapDataToPercentageGrid,\n} from '../utils/InvestmentUtil'\n\nimport { GlobalStore } from './GlobalStore'\n\nexport class HoldingStore {\n analysisType: AnalysisType = AnalysisType.Stocks\n api = new HoldingApi('/', '')\n holdings: Holding[] = []\n holdingsLoaded = false\n globalStore: GlobalStore\n showConnectionsWidget = false\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.api = new HoldingApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n get analysisChartData() {\n return mapDataToPercentageGrid(analysisChartData(this.visibleHoldings), this.analysisType)\n }\n\n get analysisDetails() {\n return analysisDetailsData(this.visibleHoldings)[this.analysisType] || {}\n }\n\n get visibleHoldings() {\n return this.holdings.filter((holding) =>\n this.globalStore.globalUiStore.selectedAccountGuids.includes(holding.account_guid),\n )\n }\n\n // Cash counts because a cash balance renders as a synthetic donut slice.\n get hasAllocationData() {\n if (this.visibleHoldings.some(holdingHasAllocationData)) return true\n\n return this.selectedInvestmentAccounts.some((account) => (account.cash_balance ?? 0) > 0)\n }\n\n get hasAnalysisData() {\n return this.visibleHoldings.some(holdingHasStyleData)\n }\n\n get selectedInvestmentAccounts() {\n const { selectedAccountGuids } = this.globalStore.globalUiStore\n return this.globalStore.accountStore.visibleInvestmentAccounts.filter((account) =>\n selectedAccountGuids.includes(account.guid),\n )\n }\n\n setHoldings = (holdings: Holding[]) => {\n this.holdings = holdings\n this.holdingsLoaded = true\n }\n\n setShowConnectionsWidget = (value: boolean) => {\n this.showConnectionsWidget = value\n }\n\n loadHoldings = async () => {\n try {\n const holdings = await this.api.getHoldings()\n this.setHoldings(holdings)\n } catch (error) {\n this.captureError('loadHoldings', error)\n }\n }\n\n setAnalysisType = (analysisType: AnalysisType) => {\n this.analysisType = analysisType\n }\n\n updateHoldings = async (holding: Holding) => {\n this.holdingsLoaded = false\n try {\n const updatedHolding = await this.api.updateHoldings(holding)\n const updatedIndex = this.holdings.findIndex(({ guid }) => guid === holding.guid)\n\n if (updatedIndex >= 0) {\n const holdings = [...this.holdings]\n holdings[updatedIndex] = updatedHolding\n\n runInAction(() => {\n this.holdings = holdings\n this.holdingsLoaded = true\n })\n }\n } catch (error) {\n this.captureError('updateHoldings', error)\n }\n }\n\n private captureError = (action: string, error: unknown) =>\n this.globalStore.captureException(error, { store: 'HoldingStore', action })\n}\n"],"mappings":";;;;AAeA,IAAa,IAAb,MAA0B;AAAA,EACxB,eAA6B,EAAa;AAAA,EAC1C,MAAM,IAAI,EAAW,KAAK,EAAE;AAAA,EAC5B,WAAsB,CAAC;AAAA,EACvB,iBAAiB;AAAA,EACjB;AAAA,EACA,wBAAwB;AAAA,EAExB,YAAY,GAA0B;AACpC,SAAK,cAAc,GACnB,KAAK,MAAM,IAAI,EAAW,EAAY,UAAU,EAAY,cAAc,EAAY,OAAO,GAE7F,EAAmB,IAAI;AAAA,EACzB;AAAA,EAEA,IAAI,oBAAoB;AACtB,WAAO,EAAwB,EAAkB,KAAK,eAAe,GAAG,KAAK,YAAY;AAAA,EAC3F;AAAA,EAEA,IAAI,kBAAkB;AACpB,WAAO,EAAoB,KAAK,eAAe,EAAE,KAAK,YAAA,KAAiB,CAAC;AAAA,EAC1E;AAAA,EAEA,IAAI,kBAAkB;AACpB,WAAO,KAAK,SAAS,OAAA,CAAQ,MAC3B,KAAK,YAAY,cAAc,qBAAqB,SAAS,EAAQ,YAAY,CACnF;AAAA,EACF;AAAA,EAGA,IAAI,oBAAoB;AACtB,WAAI,KAAK,gBAAgB,KAAK,CAAwB,IAAU,KAEzD,KAAK,2BAA2B,KAAA,CAAM,OAAa,EAAQ,gBAAgB,KAAK,CAAC;AAAA,EAC1F;AAAA,EAEA,IAAI,kBAAkB;AACpB,WAAO,KAAK,gBAAgB,KAAK,CAAmB;AAAA,EACtD;AAAA,EAEA,IAAI,6BAA6B;AAC/B,UAAM,EAAE,sBAAA,EAAA,IAAyB,KAAK,YAAY;AAClD,WAAO,KAAK,YAAY,aAAa,0BAA0B,OAAA,CAAQ,MACrE,EAAqB,SAAS,EAAQ,IAAI,CAC5C;AAAA,EACF;AAAA,EAEA,cAAA,CAAe,MAAwB;AACrC,SAAK,WAAW,GAChB,KAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,2BAAA,CAA4B,MAAmB;AAC7C,SAAK,wBAAwB;AAAA,EAC/B;AAAA,EAEA,eAAe,YAAY;AACzB,QAAI;AACF,YAAM,IAAW,MAAM,KAAK,IAAI,YAAY;AAC5C,WAAK,YAAY,CAAQ;AAAA,IAC3B,SAAS,GAAO;AACd,WAAK,aAAa,gBAAgB,CAAK;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,kBAAA,CAAmB,MAA+B;AAChD,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,iBAAiB,OAAO,MAAqB;AAC3C,SAAK,iBAAiB;AACtB,QAAI;AACF,YAAM,IAAiB,MAAM,KAAK,IAAI,eAAe,CAAO,GACtD,IAAe,KAAK,SAAS,UAAA,CAAW,EAAE,MAAA,EAAA,MAAW,MAAS,EAAQ,IAAI;AAEhF,UAAI,KAAgB,GAAG;AACrB,cAAM,IAAW,CAAC,GAAG,KAAK,QAAQ;AAClC,QAAA,EAAS,CAAA,IAAgB,GAEzB,EAAA,MAAkB;AAChB,eAAK,WAAW,GAChB,KAAK,iBAAiB;AAAA,QACxB,CAAC;AAAA,MACH;AAAA,IACF,SAAS,GAAO;AACd,WAAK,aAAa,kBAAkB,CAAK;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,eAAA,CAAwB,GAAgB,MACtC,KAAK,YAAY,iBAAiB,GAAO;AAAA,IAAE,OAAO;AAAA,IAAgB,QAAA;AAAA,EAAO,CAAC;AAC9E"}
|
|
@@ -73,6 +73,7 @@ export declare class TransactionStore {
|
|
|
73
73
|
/** Resolves `true` when the transaction was saved, `false` when the API call failed. */
|
|
74
74
|
updateTransaction: (transaction: Transaction) => Promise<boolean>;
|
|
75
75
|
loadEmbeddedInstanceTransactions: (fromDate: Date) => Promise<void>;
|
|
76
|
+
private captureError;
|
|
76
77
|
}
|
|
77
78
|
export declare class UiStore {
|
|
78
79
|
beginDate: Date;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { TransactionType as T } from "../types/Transaction.es.js";
|
|
2
2
|
import { endOfUtcDay as d, startOfUtcDay as g } from "../utils/DateUtil.es.js";
|
|
3
|
-
import { BeatApi as
|
|
4
|
-
import { TransactionApi as
|
|
3
|
+
import { BeatApi as h } from "../api/BeatApi.es.js";
|
|
4
|
+
import { TransactionApi as l } from "../api/TransactionApi.es.js";
|
|
5
5
|
import { upsertByGuid as f } from "../utils/upsertByGuid.es.js";
|
|
6
|
-
import { TABLE_CONST as
|
|
7
|
-
import { COLUMN_NAMES as
|
|
8
|
-
import { buildDetailedTransactions as
|
|
9
|
-
import { endOfMonth as
|
|
10
|
-
import { isBefore as
|
|
6
|
+
import { TABLE_CONST as y } from "../constants/Table.es.js";
|
|
7
|
+
import { COLUMN_NAMES as S, DEFAULT_TRANSACTION as m } from "../constants/Transaction.es.js";
|
|
8
|
+
import { buildDetailedTransactions as L, flattenTransactionsWithSplits as w, sortAndFilterTransactions as D } from "../utils/TransactionUtils.es.js";
|
|
9
|
+
import { endOfMonth as A } from "date-fns/endOfMonth";
|
|
10
|
+
import { isBefore as R } from "date-fns/isBefore";
|
|
11
11
|
import { startOfMonth as u } from "date-fns/startOfMonth";
|
|
12
12
|
import { startOfToday as c } from "date-fns/startOfToday";
|
|
13
|
-
import { subDays as
|
|
14
|
-
import { formatISO as
|
|
15
|
-
import { makeAutoObservable as p, runInAction as
|
|
13
|
+
import { subDays as E } from "date-fns/subDays";
|
|
14
|
+
import { formatISO as B } from "date-fns/formatISO";
|
|
15
|
+
import { makeAutoObservable as p, runInAction as r } from "mobx";
|
|
16
16
|
var P = class {
|
|
17
17
|
globalStore;
|
|
18
18
|
uiStore;
|
|
19
|
-
api = new
|
|
20
|
-
beatApi = new
|
|
19
|
+
api = new l("/", "");
|
|
20
|
+
beatApi = new h("/", "");
|
|
21
21
|
associatedBeats = [];
|
|
22
22
|
associatedBeatsLoaded = !1;
|
|
23
23
|
associatedBeatsLoading = !1;
|
|
@@ -34,14 +34,14 @@ var P = class {
|
|
|
34
34
|
transactionRulesLoaded = !1;
|
|
35
35
|
transactionRulesLoading = !1;
|
|
36
36
|
transactionSplitting = !1;
|
|
37
|
-
cachedStartDate =
|
|
37
|
+
cachedStartDate = E(c(), 90);
|
|
38
38
|
filter = {};
|
|
39
39
|
isLoading = !0;
|
|
40
40
|
alert = "";
|
|
41
|
-
sortColumn =
|
|
42
|
-
sortDirection =
|
|
41
|
+
sortColumn = S.DATE;
|
|
42
|
+
sortDirection = y.DESC;
|
|
43
43
|
constructor(t) {
|
|
44
|
-
this.globalStore = t, this.uiStore = new
|
|
44
|
+
this.globalStore = t, this.uiStore = new b(), this.api = new l(t.endpoint, t.sessionToken, t.onError), this.beatApi = new h(t.endpoint, t.sessionToken, t.onError), p(this);
|
|
45
45
|
}
|
|
46
46
|
loadTransactionData = async () => {
|
|
47
47
|
this.globalStore.accountStore.isAccountDataLoaded || await this.globalStore.accountStore.loadAccountData(), this.globalStore.categoryStore.categoriesLoaded || await this.globalStore.categoryStore.loadCategories(), await Promise.all([
|
|
@@ -56,13 +56,13 @@ var P = class {
|
|
|
56
56
|
return this.associatedBeatsLoaded && this.tagsLoaded && this.taggingsLoaded && this.transactionRulesLoaded && this.transactionsLoaded;
|
|
57
57
|
}
|
|
58
58
|
get detailedTransactions() {
|
|
59
|
-
return this.isTransactionDataLoaded ?
|
|
59
|
+
return this.isTransactionDataLoaded ? L(this.transactions, this.globalStore.accountStore.visibleAccounts, this.globalStore.categoryStore.categories, this.taggings, this.globalStore.copyStore.copy.categories) : [];
|
|
60
60
|
}
|
|
61
61
|
get sortedTransactions() {
|
|
62
|
-
return
|
|
62
|
+
return D(this.filter, this.uiStore.expandedSplits, this.sortColumn, this.sortDirection, this.tags, this.detailedTransactions);
|
|
63
63
|
}
|
|
64
64
|
get sortedTransactionsWithSplits() {
|
|
65
|
-
return
|
|
65
|
+
return w(this.sortedTransactions, this.detailedTransactions);
|
|
66
66
|
}
|
|
67
67
|
setAssociatedBeats = (t) => {
|
|
68
68
|
this.associatedBeats = t, this.associatedBeatsLoading = !1, this.associatedBeatsLoaded = !0;
|
|
@@ -86,7 +86,7 @@ var P = class {
|
|
|
86
86
|
try {
|
|
87
87
|
await this.api.addTag({ name: t }), await this.loadTags();
|
|
88
88
|
} catch (a) {
|
|
89
|
-
|
|
89
|
+
this.captureError("addTag", a);
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
92
|
addTagging = async (t, a) => {
|
|
@@ -96,7 +96,7 @@ var P = class {
|
|
|
96
96
|
transaction_guid: a
|
|
97
97
|
});
|
|
98
98
|
} catch (s) {
|
|
99
|
-
|
|
99
|
+
this.captureError("addTagging", s);
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
102
|
addOrUpdateTransactionRule = async (t, a) => {
|
|
@@ -112,32 +112,32 @@ var P = class {
|
|
|
112
112
|
match_description: a.description
|
|
113
113
|
}), await this.loadTransactionRules(), !0;
|
|
114
114
|
} catch (s) {
|
|
115
|
-
return
|
|
115
|
+
return this.captureError("addOrUpdateTransactionRule", s), !1;
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
118
|
addTransaction = async (t) => {
|
|
119
119
|
try {
|
|
120
120
|
const a = await this.api.addTransaction(t);
|
|
121
|
-
a &&
|
|
121
|
+
a && r(() => {
|
|
122
122
|
this.setTransactions(f(this.transactions, a, !0));
|
|
123
123
|
const s = a.transaction_type === T.CREDIT ? a.amount : -a.amount;
|
|
124
124
|
this.globalStore.accountStore.updateAccountBalance(a.account_guid, s);
|
|
125
125
|
});
|
|
126
126
|
} catch (a) {
|
|
127
|
-
|
|
127
|
+
this.captureError("addTransaction", a);
|
|
128
128
|
}
|
|
129
129
|
};
|
|
130
130
|
loadAssociatedBeats = async (t) => {
|
|
131
131
|
if (this.associatedBeatsLoading) return;
|
|
132
132
|
this.associatedBeatsLoading = !0;
|
|
133
|
-
const a = t ?
|
|
133
|
+
const a = t ? B(t, { representation: "date" }) : void 0;
|
|
134
134
|
try {
|
|
135
135
|
const s = await this.beatApi.getBeatsWithAssociatedTransaction(a);
|
|
136
136
|
this.setAssociatedBeats(s);
|
|
137
137
|
} catch (s) {
|
|
138
|
-
|
|
138
|
+
this.captureError("loadAssociatedBeats", s), this.setAssociatedBeats([]);
|
|
139
139
|
} finally {
|
|
140
|
-
|
|
140
|
+
r(() => {
|
|
141
141
|
this.associatedBeatsLoading = !1;
|
|
142
142
|
});
|
|
143
143
|
}
|
|
@@ -149,9 +149,9 @@ var P = class {
|
|
|
149
149
|
const t = await this.api.getTags();
|
|
150
150
|
this.setTags(t);
|
|
151
151
|
} catch (t) {
|
|
152
|
-
|
|
152
|
+
this.captureError("loadTags", t);
|
|
153
153
|
} finally {
|
|
154
|
-
|
|
154
|
+
r(() => {
|
|
155
155
|
this.tagsLoading = !1;
|
|
156
156
|
});
|
|
157
157
|
}
|
|
@@ -164,9 +164,9 @@ var P = class {
|
|
|
164
164
|
const t = await this.api.getTaggings();
|
|
165
165
|
this.setTaggings(t);
|
|
166
166
|
} catch (t) {
|
|
167
|
-
|
|
167
|
+
this.captureError("loadTaggings", t), this.setTaggings([]);
|
|
168
168
|
} finally {
|
|
169
|
-
|
|
169
|
+
r(() => {
|
|
170
170
|
this.taggingsLoading = !1;
|
|
171
171
|
});
|
|
172
172
|
}
|
|
@@ -179,9 +179,9 @@ var P = class {
|
|
|
179
179
|
const t = await this.api.getTransactionRules();
|
|
180
180
|
this.setTransactionRules(t);
|
|
181
181
|
} catch (t) {
|
|
182
|
-
|
|
182
|
+
this.captureError("loadTransactionRules", t), this.setTransactionRules([]);
|
|
183
183
|
} finally {
|
|
184
|
-
|
|
184
|
+
r(() => {
|
|
185
185
|
this.transactionRulesLoading = !1;
|
|
186
186
|
});
|
|
187
187
|
}
|
|
@@ -192,13 +192,13 @@ var P = class {
|
|
|
192
192
|
this.setIsLoading(!0), this.transactionsLoading = !0;
|
|
193
193
|
try {
|
|
194
194
|
const a = await this.api.getTransactionsByDateRange(g(t), d(c()));
|
|
195
|
-
this.setTransactions(a),
|
|
195
|
+
this.setTransactions(a), r(() => {
|
|
196
196
|
this.cachedStartDate = t;
|
|
197
197
|
});
|
|
198
198
|
} catch (a) {
|
|
199
|
-
|
|
199
|
+
this.captureError("loadTransactions", a);
|
|
200
200
|
} finally {
|
|
201
|
-
|
|
201
|
+
r(() => {
|
|
202
202
|
this.transactionsLoading = !1;
|
|
203
203
|
}), this.setIsLoading(!1);
|
|
204
204
|
}
|
|
@@ -214,14 +214,14 @@ var P = class {
|
|
|
214
214
|
try {
|
|
215
215
|
await this.api.removeTag(t), await this.loadTags();
|
|
216
216
|
} catch (a) {
|
|
217
|
-
|
|
217
|
+
this.captureError("removeTag", a);
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
220
|
removeTagging = async (t) => {
|
|
221
221
|
try {
|
|
222
222
|
await this.api.removeTagging(t);
|
|
223
223
|
} catch (a) {
|
|
224
|
-
|
|
224
|
+
this.captureError("removeTagging", a);
|
|
225
225
|
}
|
|
226
226
|
};
|
|
227
227
|
removeTransaction = async (t) => {
|
|
@@ -233,11 +233,11 @@ var P = class {
|
|
|
233
233
|
s.splice(a, 1), this.setTransactions(s);
|
|
234
234
|
}
|
|
235
235
|
} catch (a) {
|
|
236
|
-
|
|
236
|
+
this.captureError("removeTransaction", a);
|
|
237
237
|
}
|
|
238
238
|
};
|
|
239
239
|
setFilter = (t) => {
|
|
240
|
-
this.filter = t, t.dateRange &&
|
|
240
|
+
this.filter = t, t.dateRange && R(t.dateRange.start, this.cachedStartDate) && this.loadTransactions(t.dateRange.start);
|
|
241
241
|
};
|
|
242
242
|
setIsLoading = (t) => this.isLoading = t;
|
|
243
243
|
splitTransaction = async (t, a) => {
|
|
@@ -246,21 +246,21 @@ var P = class {
|
|
|
246
246
|
try {
|
|
247
247
|
const s = await this.api.updateTransaction(t), e = [];
|
|
248
248
|
for (let i = 0; i < a.length; i++) {
|
|
249
|
-
const
|
|
250
|
-
e.push(
|
|
249
|
+
const o = await this.api.addTransaction(a[i]);
|
|
250
|
+
e.push(o);
|
|
251
251
|
}
|
|
252
|
-
const
|
|
253
|
-
if (
|
|
254
|
-
const i = this.transactions.filter((
|
|
252
|
+
const n = this.transactions.findIndex((i) => i.guid === t.guid);
|
|
253
|
+
if (n >= 0) {
|
|
254
|
+
const i = this.transactions.filter((o) => o.guid !== t.guid && o.parent_guid !== t.guid);
|
|
255
255
|
this.setTransactions([
|
|
256
|
-
...i.slice(0,
|
|
256
|
+
...i.slice(0, n),
|
|
257
257
|
s,
|
|
258
258
|
...e,
|
|
259
|
-
...i.slice(
|
|
259
|
+
...i.slice(n)
|
|
260
260
|
]);
|
|
261
261
|
}
|
|
262
262
|
} catch (s) {
|
|
263
|
-
throw
|
|
263
|
+
throw this.captureError("splitTransaction", s), s;
|
|
264
264
|
} finally {
|
|
265
265
|
this.transactionSplitting = !1;
|
|
266
266
|
}
|
|
@@ -268,41 +268,41 @@ var P = class {
|
|
|
268
268
|
};
|
|
269
269
|
unSplitTransaction = async (t) => {
|
|
270
270
|
try {
|
|
271
|
-
const a = this.transactions.filter((
|
|
271
|
+
const a = this.transactions.filter((n) => n.parent_guid === t);
|
|
272
272
|
await this.api.removeTransactionSplit(t);
|
|
273
273
|
const s = [...this.transactions];
|
|
274
|
-
a.forEach((
|
|
275
|
-
const i = s.findIndex((
|
|
274
|
+
a.forEach((n) => {
|
|
275
|
+
const i = s.findIndex((o) => o.guid === n.guid);
|
|
276
276
|
i >= 0 && s.splice(i, 1);
|
|
277
277
|
});
|
|
278
|
-
const e = s.findIndex((
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
|
|
278
|
+
const e = s.findIndex((n) => n.guid === t);
|
|
279
|
+
r(() => {
|
|
280
|
+
const n = s[e];
|
|
281
|
+
n && (n.has_been_split = !1), e >= 0 && this.setTransactions([
|
|
282
282
|
...s.slice(0, e),
|
|
283
|
-
|
|
283
|
+
n,
|
|
284
284
|
...s.slice(e + 1)
|
|
285
285
|
]);
|
|
286
286
|
});
|
|
287
287
|
} catch (a) {
|
|
288
|
-
|
|
288
|
+
this.captureError("unSplitTransaction", a);
|
|
289
289
|
}
|
|
290
290
|
};
|
|
291
291
|
updateTaggings = async (t, a) => {
|
|
292
292
|
try {
|
|
293
|
-
const s = this.taggings.filter((i) => i.transaction_guid === a), e = new Set(s.map((i) => i.tag_guid)),
|
|
293
|
+
const s = this.taggings.filter((i) => i.transaction_guid === a), e = new Set(s.map((i) => i.tag_guid)), n = new Set(t);
|
|
294
294
|
for (const i of t) e.has(i) || await this.addTagging(i, a);
|
|
295
|
-
for (const i of s)
|
|
295
|
+
for (const i of s) n.has(i.tag_guid) || await this.removeTagging(i.guid);
|
|
296
296
|
await this.loadTaggings();
|
|
297
297
|
} catch (s) {
|
|
298
|
-
|
|
298
|
+
this.captureError("updateTaggings", s);
|
|
299
299
|
}
|
|
300
300
|
};
|
|
301
301
|
updateTag = async (t) => {
|
|
302
302
|
try {
|
|
303
303
|
await this.api.updateTag(t), await this.loadTags();
|
|
304
304
|
} catch (a) {
|
|
305
|
-
|
|
305
|
+
this.captureError("updateTag", a);
|
|
306
306
|
}
|
|
307
307
|
};
|
|
308
308
|
updateTransaction = async (t) => {
|
|
@@ -314,7 +314,7 @@ var P = class {
|
|
|
314
314
|
...this.transactions.slice(s + 1)
|
|
315
315
|
]), !0;
|
|
316
316
|
} catch (a) {
|
|
317
|
-
return
|
|
317
|
+
return this.captureError("updateTransaction", a), !1;
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
loadEmbeddedInstanceTransactions = async (t) => {
|
|
@@ -322,19 +322,23 @@ var P = class {
|
|
|
322
322
|
const a = await this.api.getTransactionsByDateRange(g(t), d(c()));
|
|
323
323
|
this.cachedStartDate = t, this.transactions = a;
|
|
324
324
|
} catch (a) {
|
|
325
|
-
|
|
325
|
+
this.captureError("loadEmbeddedInstanceTransactions", a);
|
|
326
326
|
}
|
|
327
327
|
};
|
|
328
|
-
|
|
328
|
+
captureError = (t, a) => this.globalStore.captureException(a, {
|
|
329
|
+
store: "TransactionStore",
|
|
330
|
+
action: t
|
|
331
|
+
});
|
|
332
|
+
}, b = class {
|
|
329
333
|
beginDate = u(/* @__PURE__ */ new Date());
|
|
330
|
-
endDate =
|
|
334
|
+
endDate = A(/* @__PURE__ */ new Date());
|
|
331
335
|
expandedSplits = [];
|
|
332
336
|
height = 550;
|
|
333
337
|
width = 1e3;
|
|
334
338
|
shouldDisableDrawerScroll = !1;
|
|
335
339
|
searchValue = "";
|
|
336
340
|
selectedAccountGuids = [];
|
|
337
|
-
manualTransaction =
|
|
341
|
+
manualTransaction = m;
|
|
338
342
|
isAmountValid = !1;
|
|
339
343
|
showInsights = !1;
|
|
340
344
|
constructor() {
|
|
@@ -366,7 +370,7 @@ var P = class {
|
|
|
366
370
|
};
|
|
367
371
|
export {
|
|
368
372
|
P as TransactionStore,
|
|
369
|
-
|
|
373
|
+
b as UiStore
|
|
370
374
|
};
|
|
371
375
|
|
|
372
376
|
//# sourceMappingURL=TransactionStore.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionStore.es.js","names":[],"sources":["../../../src/core/stores/TransactionStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { formatISO } from 'date-fns/formatISO'\nimport { isBefore } from 'date-fns/isBefore'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { subDays } from 'date-fns/subDays'\n\nimport { endOfUtcDay, startOfUtcDay } from '../utils/DateUtil'\n\nimport { BeatApi, TransactionApi } from '../api'\nimport { TABLE_CONST } from '../constants/Table'\nimport { COLUMN_NAMES, DEFAULT_TRANSACTION } from '../constants/Transaction'\nimport { TransactionType } from '../types'\nimport type { Beat, Tag, Tagging, Transaction, TransactionRule } from '../types'\nimport {\n buildDetailedTransactions,\n flattenTransactionsWithSplits,\n sortAndFilterTransactions,\n} from '../utils/TransactionUtils'\n\nimport { GlobalStore } from './GlobalStore'\nimport { upsertByGuid } from '../utils/upsertByGuid'\n\nexport type TransactionFilter = {\n accounts?: string[]\n dateRange?: { start: Date; end: Date }\n custom?: (value: Transaction) => boolean\n searchTerm?: string\n showSplits?: boolean\n}\n\nexport class TransactionStore {\n globalStore: GlobalStore\n uiStore: UiStore\n api = new TransactionApi('/', '')\n beatApi = new BeatApi('/', '')\n\n associatedBeats: Beat[] = []\n associatedBeatsLoaded: boolean = false\n associatedBeatsLoading: boolean = false\n transactions: Transaction[] = []\n transactionsLoaded: boolean = false\n transactionsLoading: boolean = false\n taggings: Tagging[] = []\n taggingsLoaded: boolean = false\n taggingsLoading: boolean = false\n tags: Tag[] = []\n tagsLoaded: boolean = false\n tagsLoading: boolean = false\n transactionRules: TransactionRule[] = []\n transactionRulesLoaded: boolean = false\n transactionRulesLoading: boolean = false\n transactionSplitting: boolean = false\n\n cachedStartDate: Date = subDays(startOfToday(), 90)\n filter: TransactionFilter = {}\n isLoading = true\n\n alert = ''\n\n sortColumn = COLUMN_NAMES.DATE\n sortDirection = TABLE_CONST.DESC\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new TransactionApi(\n globalStore.endpoint,\n globalStore.sessionToken,\n globalStore.onError,\n )\n this.beatApi = new BeatApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadTransactionData = async () => {\n if (!this.globalStore.accountStore.isAccountDataLoaded) {\n await this.globalStore.accountStore.loadAccountData()\n }\n if (!this.globalStore.categoryStore.categoriesLoaded) {\n await this.globalStore.categoryStore.loadCategories()\n }\n await Promise.all([\n this.loadAssociatedBeats(startOfMonth(new Date())),\n this.loadTags(),\n this.loadTaggings(),\n this.loadTransactionRules(),\n // By default loads 90 days of transactions\n this.loadTransactions(this.cachedStartDate),\n ])\n }\n\n get isTransactionDataLoaded(): boolean {\n return (\n this.associatedBeatsLoaded &&\n this.tagsLoaded &&\n this.taggingsLoaded &&\n this.transactionRulesLoaded &&\n this.transactionsLoaded\n )\n }\n\n get detailedTransactions(): Transaction[] {\n return this.isTransactionDataLoaded\n ? buildDetailedTransactions(\n this.transactions,\n this.globalStore.accountStore.visibleAccounts,\n this.globalStore.categoryStore.categories,\n this.taggings,\n this.globalStore.copyStore.copy.categories,\n )\n : []\n }\n\n get sortedTransactions(): Transaction[] {\n return sortAndFilterTransactions(\n this.filter,\n this.uiStore.expandedSplits,\n this.sortColumn,\n this.sortDirection,\n this.tags,\n this.detailedTransactions,\n )\n }\n\n get sortedTransactionsWithSplits(): Transaction[] {\n return flattenTransactionsWithSplits(this.sortedTransactions, this.detailedTransactions)\n }\n\n setAssociatedBeats = (beats: Beat[]) => {\n this.associatedBeats = beats\n this.associatedBeatsLoading = false\n this.associatedBeatsLoaded = true\n }\n\n setTaggings = (taggings: Tagging[]) => {\n this.taggings = taggings\n this.taggingsLoading = false\n this.taggingsLoaded = true\n }\n\n setTags = (tags: Tag[]) => {\n this.tags = tags\n this.tagsLoading = false\n this.tagsLoaded = true\n }\n\n setTransactionRules = (transactionRules: TransactionRule[]) => {\n this.transactionRules = transactionRules\n this.transactionRulesLoading = false\n this.transactionRulesLoaded = true\n }\n\n setTransactions = (transactions: Transaction[]) => {\n this.transactions = transactions\n this.transactionsLoading = false\n this.transactionsLoaded = true\n }\n\n setAlert = (alert: string) => {\n this.alert = alert\n }\n\n addTag = async (name: string) => {\n try {\n await this.api.addTag({ name } as Tag)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while adding tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n addTagging = async (tagGuid: string, transactionGuid: string) => {\n try {\n await this.api.addTagging({\n tag_guid: tagGuid,\n transaction_guid: transactionGuid,\n } as Tagging)\n } catch (error) {\n console.error('Error occurred while adding tagging:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n /** Resolves `true` when the rule was saved, `false` when an API call failed. */\n addOrUpdateTransactionRule = async (\n categoryGuid: string,\n transaction: Transaction,\n ): Promise<boolean> => {\n try {\n const existingRule = this.transactionRules.find(\n (rule: TransactionRule) => rule.guid === transaction.user_transaction_rule_guid,\n ) as TransactionRule | undefined\n\n if (existingRule) {\n await this.api.updateTransactionRule({\n ...existingRule,\n category_guid: categoryGuid,\n description: transaction.description,\n } as TransactionRule)\n } else {\n await this.api.addTransactionRule({\n category_guid: categoryGuid,\n description: transaction.description,\n match_description: transaction.description,\n } as TransactionRule)\n }\n await this.loadTransactionRules()\n return true\n } catch (error) {\n console.error('Error occurred while adding/updating transaction rule:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n return false\n }\n }\n\n addTransaction = async (transaction: Transaction) => {\n try {\n const newTransaction = await this.api.addTransaction(transaction)\n\n if (newTransaction) {\n runInAction(() => {\n this.setTransactions(upsertByGuid(this.transactions, newTransaction, true))\n\n // Brokaw may insert the transaction via WebSocket, but it never\n // updates the account balance — that only happens here.\n // See: money-dashboard/src/util/BrokawClient.ts::handleTransactionEvents (search \"setTransactions\")\n // If that handler ever calls updateAccountBalance, remove this call or guard on !existing.\n const balanceChange =\n newTransaction.transaction_type === TransactionType.CREDIT\n ? newTransaction.amount\n : -newTransaction.amount\n\n this.globalStore.accountStore.updateAccountBalance(\n newTransaction.account_guid,\n balanceChange,\n )\n })\n }\n } catch (error) {\n console.error('Error occurred while adding transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n loadAssociatedBeats = async (fromDate?: Date) => {\n if (this.associatedBeatsLoading) return\n\n this.associatedBeatsLoading = true\n const fromDateISO = fromDate ? formatISO(fromDate, { representation: 'date' }) : undefined\n try {\n const beats = await this.beatApi.getBeatsWithAssociatedTransaction(fromDateISO)\n this.setAssociatedBeats(beats)\n } catch (error) {\n console.error('Error occurred while loading associated beats:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setAssociatedBeats([])\n } finally {\n // Clear the in-flight flag even on failure so a later load (e.g. a widget\n // remount) can retry instead of being no-oped by the guard above, which would\n // leave isTransactionDataLoaded false and the list empty until a hard refresh.\n runInAction(() => {\n this.associatedBeatsLoading = false\n })\n }\n }\n\n loadTags = async () => {\n if (this.tagsLoading) return\n\n this.tagsLoading = true\n try {\n const tags = await this.api.getTags()\n this.setTags(tags)\n } catch (error) {\n console.error('Error occurred while loading tags:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n } finally {\n runInAction(() => {\n this.tagsLoading = false\n })\n }\n }\n\n loadTaggings = async () => {\n if (this.taggingsLoading) return\n\n this.taggingsLoading = true\n try {\n const taggings = await this.api.getTaggings()\n this.setTaggings(taggings)\n } catch (error) {\n console.error('Error occurred while loading taggings:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setTaggings([])\n } finally {\n runInAction(() => {\n this.taggingsLoading = false\n })\n }\n }\n\n loadTransactionRules = async () => {\n if (this.transactionRulesLoading) return\n\n this.transactionRulesLoading = true\n try {\n const transactionRules = await this.api.getTransactionRules()\n this.setTransactionRules(transactionRules)\n } catch (error) {\n // Catch so a rejection can't abort the Promise.all in loadTransactionData.\n console.error('Error occurred while loading transaction rules:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n this.setTransactionRules([])\n } finally {\n runInAction(() => {\n this.transactionRulesLoading = false\n })\n }\n }\n\n loadTransactions = async (startDate: Date = this.cachedStartDate) => {\n if (this.transactionsLoading) return\n\n this.setIsLoading(true)\n this.transactionsLoading = true\n\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n startOfUtcDay(startDate),\n endOfUtcDay(startOfToday()),\n )\n this.setTransactions(transactions)\n // Advance the cache only after the range is actually loaded, so the invariant\n // \"we hold transactions back to cachedStartDate\" always holds.\n runInAction(() => {\n this.cachedStartDate = startDate\n })\n } catch (error) {\n console.error('Error occurred while loading transactions:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n } finally {\n // See loadAssociatedBeats: clear the flag on failure so retries aren't no-oped.\n runInAction(() => {\n this.transactionsLoading = false\n })\n this.setIsLoading(false)\n }\n }\n\n modifyTransactionByAccountGuid = (guid: string, updates: Partial<Transaction>) => {\n this.transactions = this.transactions.map((txn) =>\n txn.account_guid === guid ? { ...txn, ...updates } : txn,\n )\n }\n\n removeTag = async (tagGuid: string) => {\n try {\n await this.api.removeTag(tagGuid)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while removing tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n removeTagging = async (taggingGuid: string) => {\n try {\n await this.api.removeTagging(taggingGuid)\n } catch (error) {\n console.error('Error occurred while removing tagging:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n removeTransaction = async (transactionGuid: string) => {\n try {\n await this.api.removeTransaction(transactionGuid)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transactionGuid)\n\n if (index >= 0) {\n const updatedTransactions = [...this.transactions]\n updatedTransactions.splice(index, 1)\n this.setTransactions(updatedTransactions)\n }\n } catch (error) {\n console.error('Error occurred while removing transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n setFilter = (filter: TransactionFilter) => {\n this.filter = filter\n\n // Only reload if the new start date is prior to the cached start date; end date\n // is always today. loadTransactions advances cachedStartDate on success, so we\n // must not advance it here (a skipped/failed load would leave the list empty).\n if (filter.dateRange && isBefore(filter.dateRange.start, this.cachedStartDate)) {\n this.loadTransactions(filter.dateRange.start)\n }\n }\n\n setIsLoading = (isLoading: boolean) => (this.isLoading = isLoading)\n\n splitTransaction = async (transaction: Transaction, splits: Transaction[]) => {\n if (this.transactionSplitting) return\n this.transactionSplitting = true\n\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n const children = [] as Transaction[]\n\n for (let i = 0; i < splits.length; i++) {\n const child = await this.api.addTransaction(splits[i])\n children.push(child)\n }\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n // Remove old parent and any existing children\n const filtered = this.transactions.filter(\n (t) => t.guid !== transaction.guid && t.parent_guid !== transaction.guid,\n )\n\n // Insert updated parent + new children at original position\n this.setTransactions([\n ...filtered.slice(0, index),\n updatedTransaction,\n ...children,\n ...filtered.slice(index),\n ])\n }\n } catch (error) {\n console.error('Error occurred while splitting transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n throw error\n } finally {\n this.transactionSplitting = false\n }\n }\n\n unSplitTransaction = async (guid: string) => {\n try {\n const children = this.transactions.filter((t) => t.parent_guid === guid)\n\n await this.api.removeTransactionSplit(guid)\n\n // Remove children\n const transactions = [...this.transactions]\n children.forEach((child) => {\n const index = transactions.findIndex((t) => t.guid === child.guid)\n\n if (index >= 0) {\n transactions.splice(index, 1)\n }\n })\n\n // Update parent\n const index = transactions.findIndex((t) => t.guid === guid)\n\n runInAction(() => {\n const transaction = transactions[index]\n if (transaction) {\n transaction.has_been_split = false\n }\n\n if (index >= 0) {\n this.setTransactions([\n ...transactions.slice(0, index),\n transaction,\n ...transactions.slice(index + 1),\n ])\n }\n })\n } catch (error) {\n console.error('Error occurred while unsplitting transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTaggings = async (tagGuids: string[], transactionGuid: string) => {\n try {\n const currentTaggings = this.taggings.filter((t) => t.transaction_guid === transactionGuid)\n\n const currentTagGuids = new Set(currentTaggings.map((t) => t.tag_guid))\n const incomingTagGuids = new Set(tagGuids)\n\n // Add new taggings that don't already exist\n for (const tagGuid of tagGuids) {\n if (!currentTagGuids.has(tagGuid)) {\n await this.addTagging(tagGuid, transactionGuid)\n }\n }\n\n // Remove taggings that are no longer needed\n for (const tagging of currentTaggings) {\n if (!incomingTagGuids.has(tagging.tag_guid)) {\n await this.removeTagging(tagging.guid)\n }\n }\n\n await this.loadTaggings()\n } catch (error) {\n console.error('Error occurred while updating taggings:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n updateTag = async (tag: Tag) => {\n try {\n await this.api.updateTag(tag)\n await this.loadTags()\n } catch (error) {\n console.error('Error occurred while updating tag:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n\n /** Resolves `true` when the transaction was saved, `false` when the API call failed. */\n updateTransaction = async (transaction: Transaction): Promise<boolean> => {\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n this.setTransactions([\n ...this.transactions.slice(0, index),\n updatedTransaction,\n ...this.transactions.slice(index + 1),\n ])\n }\n return true\n } catch (error) {\n console.error('Error occurred while updating transaction:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n return false\n }\n }\n\n // This is used for loading the transactions list on demand, on clicking the different transactions of the insightful beats.\n loadEmbeddedInstanceTransactions = async (fromDate: Date) => {\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n startOfUtcDay(fromDate),\n endOfUtcDay(startOfToday()),\n )\n this.cachedStartDate = fromDate\n this.transactions = transactions\n } catch (error) {\n console.error('Error occurred while loading embedded instance transactions:', error)\n this.globalStore.captureException(error, { store: 'TransactionStore' })\n }\n }\n}\n\nexport class UiStore {\n beginDate = startOfMonth(new Date())\n endDate = endOfMonth(new Date())\n\n expandedSplits = [] as string[]\n height = 550\n width = 1000\n shouldDisableDrawerScroll = false\n\n searchValue = ''\n selectedAccountGuids = [] as string[]\n\n manualTransaction: Transaction = DEFAULT_TRANSACTION\n isAmountValid = false\n\n showInsights = false\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setDateRange = (beginDate: Date, endDate: Date) => {\n this.beginDate = beginDate\n this.endDate = endDate\n }\n\n setIsAmountValid = (valid: boolean) => (this.isAmountValid = valid)\n\n setSearchValue = (searchValue: string) => (this.searchValue = searchValue)\n\n setSelectedAccountGuids = (accountGuids: string[]) => (this.selectedAccountGuids = accountGuids)\n\n setShouldDisableDrawerScroll = (shouldDisable: boolean) =>\n (this.shouldDisableDrawerScroll = shouldDisable)\n\n setShowInsights = (showInsights: boolean) => {\n this.showInsights = showInsights\n }\n\n setSize = (height: number, width: number) => {\n this.height = height\n this.width = width\n }\n\n toggleSplit = (guid: string) => {\n const expandedSplits = [...this.expandedSplits]\n const index = this.expandedSplits.findIndex((splitGuid) => splitGuid === guid)\n\n if (index >= 0) {\n expandedSplits.splice(index, 1)\n } else {\n expandedSplits.push(guid)\n }\n\n this.expandedSplits = expandedSplits\n }\n\n clearExpandedSplits = () => {\n if (this.expandedSplits.length === 0) return\n this.expandedSplits = []\n }\n\n updateManualTransaction = (manualTransaction: Transaction) => {\n this.manualTransaction = manualTransaction\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TransactionStore.es.js","names":[],"sources":["../../../src/core/stores/TransactionStore.ts"],"sourcesContent":["import { makeAutoObservable, runInAction } from 'mobx'\nimport { endOfMonth } from 'date-fns/endOfMonth'\nimport { formatISO } from 'date-fns/formatISO'\nimport { isBefore } from 'date-fns/isBefore'\nimport { startOfMonth } from 'date-fns/startOfMonth'\nimport { startOfToday } from 'date-fns/startOfToday'\nimport { subDays } from 'date-fns/subDays'\n\nimport { endOfUtcDay, startOfUtcDay } from '../utils/DateUtil'\n\nimport { BeatApi, TransactionApi } from '../api'\nimport { TABLE_CONST } from '../constants/Table'\nimport { COLUMN_NAMES, DEFAULT_TRANSACTION } from '../constants/Transaction'\nimport { TransactionType } from '../types'\nimport type { Beat, Tag, Tagging, Transaction, TransactionRule } from '../types'\nimport {\n buildDetailedTransactions,\n flattenTransactionsWithSplits,\n sortAndFilterTransactions,\n} from '../utils/TransactionUtils'\n\nimport { GlobalStore } from './GlobalStore'\nimport { upsertByGuid } from '../utils/upsertByGuid'\n\nexport type TransactionFilter = {\n accounts?: string[]\n dateRange?: { start: Date; end: Date }\n custom?: (value: Transaction) => boolean\n searchTerm?: string\n showSplits?: boolean\n}\n\nexport class TransactionStore {\n globalStore: GlobalStore\n uiStore: UiStore\n api = new TransactionApi('/', '')\n beatApi = new BeatApi('/', '')\n\n associatedBeats: Beat[] = []\n associatedBeatsLoaded: boolean = false\n associatedBeatsLoading: boolean = false\n transactions: Transaction[] = []\n transactionsLoaded: boolean = false\n transactionsLoading: boolean = false\n taggings: Tagging[] = []\n taggingsLoaded: boolean = false\n taggingsLoading: boolean = false\n tags: Tag[] = []\n tagsLoaded: boolean = false\n tagsLoading: boolean = false\n transactionRules: TransactionRule[] = []\n transactionRulesLoaded: boolean = false\n transactionRulesLoading: boolean = false\n transactionSplitting: boolean = false\n\n cachedStartDate: Date = subDays(startOfToday(), 90)\n filter: TransactionFilter = {}\n isLoading = true\n\n alert = ''\n\n sortColumn = COLUMN_NAMES.DATE\n sortDirection = TABLE_CONST.DESC\n\n constructor(globalStore: GlobalStore) {\n this.globalStore = globalStore\n this.uiStore = new UiStore()\n this.api = new TransactionApi(\n globalStore.endpoint,\n globalStore.sessionToken,\n globalStore.onError,\n )\n this.beatApi = new BeatApi(globalStore.endpoint, globalStore.sessionToken, globalStore.onError)\n\n makeAutoObservable(this)\n }\n\n loadTransactionData = async () => {\n if (!this.globalStore.accountStore.isAccountDataLoaded) {\n await this.globalStore.accountStore.loadAccountData()\n }\n if (!this.globalStore.categoryStore.categoriesLoaded) {\n await this.globalStore.categoryStore.loadCategories()\n }\n await Promise.all([\n this.loadAssociatedBeats(startOfMonth(new Date())),\n this.loadTags(),\n this.loadTaggings(),\n this.loadTransactionRules(),\n // By default loads 90 days of transactions\n this.loadTransactions(this.cachedStartDate),\n ])\n }\n\n get isTransactionDataLoaded(): boolean {\n return (\n this.associatedBeatsLoaded &&\n this.tagsLoaded &&\n this.taggingsLoaded &&\n this.transactionRulesLoaded &&\n this.transactionsLoaded\n )\n }\n\n get detailedTransactions(): Transaction[] {\n return this.isTransactionDataLoaded\n ? buildDetailedTransactions(\n this.transactions,\n this.globalStore.accountStore.visibleAccounts,\n this.globalStore.categoryStore.categories,\n this.taggings,\n this.globalStore.copyStore.copy.categories,\n )\n : []\n }\n\n get sortedTransactions(): Transaction[] {\n return sortAndFilterTransactions(\n this.filter,\n this.uiStore.expandedSplits,\n this.sortColumn,\n this.sortDirection,\n this.tags,\n this.detailedTransactions,\n )\n }\n\n get sortedTransactionsWithSplits(): Transaction[] {\n return flattenTransactionsWithSplits(this.sortedTransactions, this.detailedTransactions)\n }\n\n setAssociatedBeats = (beats: Beat[]) => {\n this.associatedBeats = beats\n this.associatedBeatsLoading = false\n this.associatedBeatsLoaded = true\n }\n\n setTaggings = (taggings: Tagging[]) => {\n this.taggings = taggings\n this.taggingsLoading = false\n this.taggingsLoaded = true\n }\n\n setTags = (tags: Tag[]) => {\n this.tags = tags\n this.tagsLoading = false\n this.tagsLoaded = true\n }\n\n setTransactionRules = (transactionRules: TransactionRule[]) => {\n this.transactionRules = transactionRules\n this.transactionRulesLoading = false\n this.transactionRulesLoaded = true\n }\n\n setTransactions = (transactions: Transaction[]) => {\n this.transactions = transactions\n this.transactionsLoading = false\n this.transactionsLoaded = true\n }\n\n setAlert = (alert: string) => {\n this.alert = alert\n }\n\n addTag = async (name: string) => {\n try {\n await this.api.addTag({ name } as Tag)\n await this.loadTags()\n } catch (error) {\n this.captureError('addTag', error)\n }\n }\n\n addTagging = async (tagGuid: string, transactionGuid: string) => {\n try {\n await this.api.addTagging({\n tag_guid: tagGuid,\n transaction_guid: transactionGuid,\n } as Tagging)\n } catch (error) {\n this.captureError('addTagging', error)\n }\n }\n\n /** Resolves `true` when the rule was saved, `false` when an API call failed. */\n addOrUpdateTransactionRule = async (\n categoryGuid: string,\n transaction: Transaction,\n ): Promise<boolean> => {\n try {\n const existingRule = this.transactionRules.find(\n (rule: TransactionRule) => rule.guid === transaction.user_transaction_rule_guid,\n ) as TransactionRule | undefined\n\n if (existingRule) {\n await this.api.updateTransactionRule({\n ...existingRule,\n category_guid: categoryGuid,\n description: transaction.description,\n } as TransactionRule)\n } else {\n await this.api.addTransactionRule({\n category_guid: categoryGuid,\n description: transaction.description,\n match_description: transaction.description,\n } as TransactionRule)\n }\n await this.loadTransactionRules()\n return true\n } catch (error) {\n this.captureError('addOrUpdateTransactionRule', error)\n return false\n }\n }\n\n addTransaction = async (transaction: Transaction) => {\n try {\n const newTransaction = await this.api.addTransaction(transaction)\n\n if (newTransaction) {\n runInAction(() => {\n this.setTransactions(upsertByGuid(this.transactions, newTransaction, true))\n\n // Brokaw may insert the transaction via WebSocket, but it never\n // updates the account balance — that only happens here.\n // See: money-dashboard/src/util/BrokawClient.ts::handleTransactionEvents (search \"setTransactions\")\n // If that handler ever calls updateAccountBalance, remove this call or guard on !existing.\n const balanceChange =\n newTransaction.transaction_type === TransactionType.CREDIT\n ? newTransaction.amount\n : -newTransaction.amount\n\n this.globalStore.accountStore.updateAccountBalance(\n newTransaction.account_guid,\n balanceChange,\n )\n })\n }\n } catch (error) {\n this.captureError('addTransaction', error)\n }\n }\n\n loadAssociatedBeats = async (fromDate?: Date) => {\n if (this.associatedBeatsLoading) return\n\n this.associatedBeatsLoading = true\n const fromDateISO = fromDate ? formatISO(fromDate, { representation: 'date' }) : undefined\n try {\n const beats = await this.beatApi.getBeatsWithAssociatedTransaction(fromDateISO)\n this.setAssociatedBeats(beats)\n } catch (error) {\n this.captureError('loadAssociatedBeats', error)\n this.setAssociatedBeats([])\n } finally {\n // Clear the in-flight flag even on failure so a later load (e.g. a widget\n // remount) can retry instead of being no-oped by the guard above, which would\n // leave isTransactionDataLoaded false and the list empty until a hard refresh.\n runInAction(() => {\n this.associatedBeatsLoading = false\n })\n }\n }\n\n loadTags = async () => {\n if (this.tagsLoading) return\n\n this.tagsLoading = true\n try {\n const tags = await this.api.getTags()\n this.setTags(tags)\n } catch (error) {\n this.captureError('loadTags', error)\n } finally {\n runInAction(() => {\n this.tagsLoading = false\n })\n }\n }\n\n loadTaggings = async () => {\n if (this.taggingsLoading) return\n\n this.taggingsLoading = true\n try {\n const taggings = await this.api.getTaggings()\n this.setTaggings(taggings)\n } catch (error) {\n this.captureError('loadTaggings', error)\n this.setTaggings([])\n } finally {\n runInAction(() => {\n this.taggingsLoading = false\n })\n }\n }\n\n loadTransactionRules = async () => {\n if (this.transactionRulesLoading) return\n\n this.transactionRulesLoading = true\n try {\n const transactionRules = await this.api.getTransactionRules()\n this.setTransactionRules(transactionRules)\n } catch (error) {\n // Catch so a rejection can't abort the Promise.all in loadTransactionData.\n this.captureError('loadTransactionRules', error)\n this.setTransactionRules([])\n } finally {\n runInAction(() => {\n this.transactionRulesLoading = false\n })\n }\n }\n\n loadTransactions = async (startDate: Date = this.cachedStartDate) => {\n if (this.transactionsLoading) return\n\n this.setIsLoading(true)\n this.transactionsLoading = true\n\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n startOfUtcDay(startDate),\n endOfUtcDay(startOfToday()),\n )\n this.setTransactions(transactions)\n // Advance the cache only after the range is actually loaded, so the invariant\n // \"we hold transactions back to cachedStartDate\" always holds.\n runInAction(() => {\n this.cachedStartDate = startDate\n })\n } catch (error) {\n this.captureError('loadTransactions', error)\n } finally {\n // See loadAssociatedBeats: clear the flag on failure so retries aren't no-oped.\n runInAction(() => {\n this.transactionsLoading = false\n })\n this.setIsLoading(false)\n }\n }\n\n modifyTransactionByAccountGuid = (guid: string, updates: Partial<Transaction>) => {\n this.transactions = this.transactions.map((txn) =>\n txn.account_guid === guid ? { ...txn, ...updates } : txn,\n )\n }\n\n removeTag = async (tagGuid: string) => {\n try {\n await this.api.removeTag(tagGuid)\n await this.loadTags()\n } catch (error) {\n this.captureError('removeTag', error)\n }\n }\n\n removeTagging = async (taggingGuid: string) => {\n try {\n await this.api.removeTagging(taggingGuid)\n } catch (error) {\n this.captureError('removeTagging', error)\n }\n }\n\n removeTransaction = async (transactionGuid: string) => {\n try {\n await this.api.removeTransaction(transactionGuid)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transactionGuid)\n\n if (index >= 0) {\n const updatedTransactions = [...this.transactions]\n updatedTransactions.splice(index, 1)\n this.setTransactions(updatedTransactions)\n }\n } catch (error) {\n this.captureError('removeTransaction', error)\n }\n }\n\n setFilter = (filter: TransactionFilter) => {\n this.filter = filter\n\n // Only reload if the new start date is prior to the cached start date; end date\n // is always today. loadTransactions advances cachedStartDate on success, so we\n // must not advance it here (a skipped/failed load would leave the list empty).\n if (filter.dateRange && isBefore(filter.dateRange.start, this.cachedStartDate)) {\n this.loadTransactions(filter.dateRange.start)\n }\n }\n\n setIsLoading = (isLoading: boolean) => (this.isLoading = isLoading)\n\n splitTransaction = async (transaction: Transaction, splits: Transaction[]) => {\n if (this.transactionSplitting) return\n this.transactionSplitting = true\n\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n const children = [] as Transaction[]\n\n for (let i = 0; i < splits.length; i++) {\n const child = await this.api.addTransaction(splits[i])\n children.push(child)\n }\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n // Remove old parent and any existing children\n const filtered = this.transactions.filter(\n (t) => t.guid !== transaction.guid && t.parent_guid !== transaction.guid,\n )\n\n // Insert updated parent + new children at original position\n this.setTransactions([\n ...filtered.slice(0, index),\n updatedTransaction,\n ...children,\n ...filtered.slice(index),\n ])\n }\n } catch (error) {\n this.captureError('splitTransaction', error)\n throw error\n } finally {\n this.transactionSplitting = false\n }\n }\n\n unSplitTransaction = async (guid: string) => {\n try {\n const children = this.transactions.filter((t) => t.parent_guid === guid)\n\n await this.api.removeTransactionSplit(guid)\n\n // Remove children\n const transactions = [...this.transactions]\n children.forEach((child) => {\n const index = transactions.findIndex((t) => t.guid === child.guid)\n\n if (index >= 0) {\n transactions.splice(index, 1)\n }\n })\n\n // Update parent\n const index = transactions.findIndex((t) => t.guid === guid)\n\n runInAction(() => {\n const transaction = transactions[index]\n if (transaction) {\n transaction.has_been_split = false\n }\n\n if (index >= 0) {\n this.setTransactions([\n ...transactions.slice(0, index),\n transaction,\n ...transactions.slice(index + 1),\n ])\n }\n })\n } catch (error) {\n this.captureError('unSplitTransaction', error)\n }\n }\n\n updateTaggings = async (tagGuids: string[], transactionGuid: string) => {\n try {\n const currentTaggings = this.taggings.filter((t) => t.transaction_guid === transactionGuid)\n\n const currentTagGuids = new Set(currentTaggings.map((t) => t.tag_guid))\n const incomingTagGuids = new Set(tagGuids)\n\n // Add new taggings that don't already exist\n for (const tagGuid of tagGuids) {\n if (!currentTagGuids.has(tagGuid)) {\n await this.addTagging(tagGuid, transactionGuid)\n }\n }\n\n // Remove taggings that are no longer needed\n for (const tagging of currentTaggings) {\n if (!incomingTagGuids.has(tagging.tag_guid)) {\n await this.removeTagging(tagging.guid)\n }\n }\n\n await this.loadTaggings()\n } catch (error) {\n this.captureError('updateTaggings', error)\n }\n }\n\n updateTag = async (tag: Tag) => {\n try {\n await this.api.updateTag(tag)\n await this.loadTags()\n } catch (error) {\n this.captureError('updateTag', error)\n }\n }\n\n /** Resolves `true` when the transaction was saved, `false` when the API call failed. */\n updateTransaction = async (transaction: Transaction): Promise<boolean> => {\n try {\n const updatedTransaction = await this.api.updateTransaction(transaction)\n\n const index = this.transactions.findIndex((t: Transaction) => t.guid === transaction.guid)\n\n if (index >= 0) {\n this.setTransactions([\n ...this.transactions.slice(0, index),\n updatedTransaction,\n ...this.transactions.slice(index + 1),\n ])\n }\n return true\n } catch (error) {\n this.captureError('updateTransaction', error)\n return false\n }\n }\n\n // This is used for loading the transactions list on demand, on clicking the different transactions of the insightful beats.\n loadEmbeddedInstanceTransactions = async (fromDate: Date) => {\n try {\n const transactions = await this.api.getTransactionsByDateRange(\n startOfUtcDay(fromDate),\n endOfUtcDay(startOfToday()),\n )\n this.cachedStartDate = fromDate\n this.transactions = transactions\n } catch (error) {\n this.captureError('loadEmbeddedInstanceTransactions', error)\n }\n }\n\n private captureError = (action: string, error: unknown) =>\n this.globalStore.captureException(error, { store: 'TransactionStore', action })\n}\n\nexport class UiStore {\n beginDate = startOfMonth(new Date())\n endDate = endOfMonth(new Date())\n\n expandedSplits = [] as string[]\n height = 550\n width = 1000\n shouldDisableDrawerScroll = false\n\n searchValue = ''\n selectedAccountGuids = [] as string[]\n\n manualTransaction: Transaction = DEFAULT_TRANSACTION\n isAmountValid = false\n\n showInsights = false\n\n constructor() {\n makeAutoObservable(this)\n }\n\n setDateRange = (beginDate: Date, endDate: Date) => {\n this.beginDate = beginDate\n this.endDate = endDate\n }\n\n setIsAmountValid = (valid: boolean) => (this.isAmountValid = valid)\n\n setSearchValue = (searchValue: string) => (this.searchValue = searchValue)\n\n setSelectedAccountGuids = (accountGuids: string[]) => (this.selectedAccountGuids = accountGuids)\n\n setShouldDisableDrawerScroll = (shouldDisable: boolean) =>\n (this.shouldDisableDrawerScroll = shouldDisable)\n\n setShowInsights = (showInsights: boolean) => {\n this.showInsights = showInsights\n }\n\n setSize = (height: number, width: number) => {\n this.height = height\n this.width = width\n }\n\n toggleSplit = (guid: string) => {\n const expandedSplits = [...this.expandedSplits]\n const index = this.expandedSplits.findIndex((splitGuid) => splitGuid === guid)\n\n if (index >= 0) {\n expandedSplits.splice(index, 1)\n } else {\n expandedSplits.push(guid)\n }\n\n this.expandedSplits = expandedSplits\n }\n\n clearExpandedSplits = () => {\n if (this.expandedSplits.length === 0) return\n this.expandedSplits = []\n }\n\n updateManualTransaction = (manualTransaction: Transaction) => {\n this.manualTransaction = manualTransaction\n }\n}\n"],"mappings":"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"}
|