@mx-cartographer/experiences 9.4.2 → 9.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/dist/core/constants/Investments.d.ts +3 -0
- package/dist/core/constants/Investments.es.js +34 -11
- package/dist/core/constants/Investments.es.js.map +1 -1
- package/dist/core/constants/repeatingTransactions.d.ts +6 -0
- package/dist/core/constants/repeatingTransactions.es.js +18 -3
- package/dist/core/constants/repeatingTransactions.es.js.map +1 -1
- package/dist/core/stores/HoldingStore.d.ts +3 -0
- package/dist/core/stores/HoldingStore.es.js +39 -29
- package/dist/core/stores/HoldingStore.es.js.map +1 -1
- package/dist/core/types/RepeatingTransaction.d.ts +2 -0
- package/dist/core/types/RepeatingTransaction.es.js.map +1 -1
- package/dist/core/types/Transaction.d.ts +1 -0
- package/dist/core/types/Transaction.es.js.map +1 -1
- package/dist/core/utils/InvestmentUtil.d.ts +4 -0
- package/dist/core/utils/InvestmentUtil.es.js +71 -58
- package/dist/core/utils/InvestmentUtil.es.js.map +1 -1
- package/dist/core/utils/RecurringTransactionsUtil.d.ts +1 -0
- package/dist/core/utils/RecurringTransactionsUtil.es.js +145 -143
- package/dist/core/utils/RecurringTransactionsUtil.es.js.map +1 -1
- package/dist/core/utils/TransactionUtils.d.ts +1 -0
- package/dist/investments/InvestmentsWidget.es.js +100 -66
- package/dist/investments/InvestmentsWidget.es.js.map +1 -1
- package/dist/investments/components/allocation/util/createInvestementsAllocationData.es.js +50 -59
- package/dist/investments/components/allocation/util/createInvestementsAllocationData.es.js.map +1 -1
- package/dist/recurringtransactions/components/shared/recurringsettings/AddRecurringTransaction.es.js +16 -14
- package/dist/recurringtransactions/components/shared/recurringsettings/AddRecurringTransaction.es.js.map +1 -1
- package/dist/recurringtransactions/components/shared/recurringsettings/SelectTransaction.es.js +19 -17
- package/dist/recurringtransactions/components/shared/recurringsettings/SelectTransaction.es.js.map +1 -1
- package/dist/transactions/components/shared/TransactionList.es.js +16 -12
- package/dist/transactions/components/shared/TransactionList.es.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
## [9.4.
|
|
1
|
+
## [9.4.4] - 08-26-2026
|
|
2
|
+
|
|
3
|
+
- **CHANGED** - Investments widget now disables (not hides) the Allocation and Analysis tabs, with an explanatory tooltip, when the selected accounts have no data to render; the active tab resets to Overview if it becomes disabled
|
|
4
|
+
- **FIXED** - The Analysis tab now stays disabled for partially-enriched holdings whose style weights fall outside the render band, so it no longer enables onto an all-zero grid
|
|
5
|
+
|
|
6
|
+
## [9.4.3] - 08-26-2026
|
|
2
7
|
|
|
8
|
+
- **ADDED** - Pass category_guid and main_class_guid when creating repeating transactions (MEW-4051)
|
|
9
|
+
- **ADDED** - Filter selectable transactions for recurring creation to merchant-backed transactions or eligible merchantless bills and income (MEW-4051)
|
|
10
|
+
|
|
11
|
+
## [9.4.2] - 08-26-2026
|
|
3
12
|
- **ADDED** - Sub budget totals now roll up to parent budget total
|
|
4
13
|
- **ADDED** - Destructive cascade delete of sub-budgets when a parent budget is deleted
|
|
5
14
|
- **REMOVED** - Un-budgeted projected income line
|
|
@@ -2,6 +2,9 @@ export declare enum AnalysisType {
|
|
|
2
2
|
Stocks = "stocks",
|
|
3
3
|
Bonds = "bonds"
|
|
4
4
|
}
|
|
5
|
+
export declare const ALLOCATION_KEYS: readonly ["allocations_cash", "allocations_convertible", "allocations_foreign_bond", "allocations_foreign_stock", "allocations_other", "allocations_preferred", "allocations_us_bond", "allocations_us_stock", "allocations_unknown"];
|
|
6
|
+
export type AllocationKey = (typeof ALLOCATION_KEYS)[number];
|
|
7
|
+
export declare const STYLE_WEIGHT_KEYS: readonly ["large_core_weight", "large_growth_weight", "large_value_weight", "mid_core_weight", "mid_growth_weight", "mid_value_weight", "small_core_weight", "small_growth_weight", "small_value_weight", "unknown_weight"];
|
|
5
8
|
export declare const EquityClassificationTypes: {
|
|
6
9
|
UNKNOWN: number;
|
|
7
10
|
LARGE_VALUE: number;
|
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
var
|
|
2
|
-
return
|
|
3
|
-
})({}),
|
|
1
|
+
var E = /* @__PURE__ */ (function(_) {
|
|
2
|
+
return _.Stocks = "stocks", _.Bonds = "bonds", _;
|
|
3
|
+
})({}), o = [
|
|
4
|
+
"allocations_cash",
|
|
5
|
+
"allocations_convertible",
|
|
6
|
+
"allocations_foreign_bond",
|
|
7
|
+
"allocations_foreign_stock",
|
|
8
|
+
"allocations_other",
|
|
9
|
+
"allocations_preferred",
|
|
10
|
+
"allocations_us_bond",
|
|
11
|
+
"allocations_us_stock",
|
|
12
|
+
"allocations_unknown"
|
|
13
|
+
], a = [
|
|
14
|
+
"large_core_weight",
|
|
15
|
+
"large_growth_weight",
|
|
16
|
+
"large_value_weight",
|
|
17
|
+
"mid_core_weight",
|
|
18
|
+
"mid_growth_weight",
|
|
19
|
+
"mid_value_weight",
|
|
20
|
+
"small_core_weight",
|
|
21
|
+
"small_growth_weight",
|
|
22
|
+
"small_value_weight",
|
|
23
|
+
"unknown_weight"
|
|
24
|
+
], i = {
|
|
4
25
|
UNKNOWN: 0,
|
|
5
26
|
LARGE_VALUE: 1,
|
|
6
27
|
LARGE_CORE: 2,
|
|
@@ -11,7 +32,7 @@ var I = /* @__PURE__ */ (function(E) {
|
|
|
11
32
|
SMALL_VALUE: 7,
|
|
12
33
|
SMALL_CORE: 8,
|
|
13
34
|
SMALL_GROWTH: 9
|
|
14
|
-
},
|
|
35
|
+
}, I = {
|
|
15
36
|
0: "UNKNOWN",
|
|
16
37
|
1: "LARGE_VALUE",
|
|
17
38
|
2: "LARGE_CORE",
|
|
@@ -22,7 +43,7 @@ var I = /* @__PURE__ */ (function(E) {
|
|
|
22
43
|
7: "SMALL_VALUE",
|
|
23
44
|
8: "SMALL_CORE",
|
|
24
45
|
9: "SMALL_GROWTH"
|
|
25
|
-
},
|
|
46
|
+
}, L = {
|
|
26
47
|
UNKNOWN: 0,
|
|
27
48
|
HIGH_LIMITED: 1,
|
|
28
49
|
HIGH_MODERATE: 2,
|
|
@@ -33,7 +54,7 @@ var I = /* @__PURE__ */ (function(E) {
|
|
|
33
54
|
LOW_LIMITED: 7,
|
|
34
55
|
LOW_MODERATE: 8,
|
|
35
56
|
LOW_EXTENSIVE: 9
|
|
36
|
-
},
|
|
57
|
+
}, t = {
|
|
37
58
|
0: "UNKNOWN",
|
|
38
59
|
1: "HIGH_LIMITED",
|
|
39
60
|
2: "HIGH_MODERATE",
|
|
@@ -46,11 +67,13 @@ var I = /* @__PURE__ */ (function(E) {
|
|
|
46
67
|
9: "LOW_EXTENSIVE"
|
|
47
68
|
};
|
|
48
69
|
export {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
70
|
+
o as ALLOCATION_KEYS,
|
|
71
|
+
E as AnalysisType,
|
|
72
|
+
i as EquityClassificationTypes,
|
|
73
|
+
I as EquityClassificationValues,
|
|
74
|
+
L as FixedIncomeClassificationTypes,
|
|
75
|
+
t as FixedIncomeClassificationValues,
|
|
76
|
+
a as STYLE_WEIGHT_KEYS
|
|
54
77
|
};
|
|
55
78
|
|
|
56
79
|
//# sourceMappingURL=Investments.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Investments.es.js","names":[],"sources":["../../../src/core/constants/Investments.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"Investments.es.js","names":[],"sources":["../../../src/core/constants/Investments.ts"],"sourcesContent":["import type { Holding } from '../types/Holding'\n\nexport enum AnalysisType {\n Stocks = 'stocks',\n Bonds = 'bonds',\n}\n\n// The nine Morningstar allocation weights on a holding. Order is significant:\n// it maps positionally to the `allocations_list` copy display names.\nexport const ALLOCATION_KEYS = [\n 'allocations_cash',\n 'allocations_convertible',\n 'allocations_foreign_bond',\n 'allocations_foreign_stock',\n 'allocations_other',\n 'allocations_preferred',\n 'allocations_us_bond',\n 'allocations_us_stock',\n 'allocations_unknown',\n] as const satisfies readonly (keyof Holding)[]\n\nexport type AllocationKey = (typeof ALLOCATION_KEYS)[number]\n\n// The ten style-box weights (equity + fixed-income share the same buckets).\nexport const STYLE_WEIGHT_KEYS = [\n 'large_core_weight',\n 'large_growth_weight',\n 'large_value_weight',\n 'mid_core_weight',\n 'mid_growth_weight',\n 'mid_value_weight',\n 'small_core_weight',\n 'small_growth_weight',\n 'small_value_weight',\n 'unknown_weight',\n] as const satisfies readonly (keyof Holding)[]\n\nexport const EquityClassificationTypes = {\n UNKNOWN: 0,\n LARGE_VALUE: 1,\n LARGE_CORE: 2,\n LARGE_GROWTH: 3,\n MID_VALUE: 4,\n MID_CORE: 5,\n MID_GROWTH: 6,\n SMALL_VALUE: 7,\n SMALL_CORE: 8,\n SMALL_GROWTH: 9,\n}\n\nexport const EquityClassificationValues = {\n 0: 'UNKNOWN',\n 1: 'LARGE_VALUE',\n 2: 'LARGE_CORE',\n 3: 'LARGE_GROWTH',\n 4: 'MID_VALUE',\n 5: 'MID_CORE',\n 6: 'MID_GROWTH',\n 7: 'SMALL_VALUE',\n 8: 'SMALL_CORE',\n 9: 'SMALL_GROWTH',\n}\n\nexport const FixedIncomeClassificationTypes = {\n UNKNOWN: 0,\n HIGH_LIMITED: 1,\n HIGH_MODERATE: 2,\n HIGH_EXTENSIVE: 3,\n MEDIUM_LIMITED: 4,\n MEDIUM_MODERATE: 5,\n MEDIUM_EXTENSIVE: 6,\n LOW_LIMITED: 7,\n LOW_MODERATE: 8,\n LOW_EXTENSIVE: 9,\n}\n\nexport const FixedIncomeClassificationValues = {\n 0: 'UNKNOWN',\n 1: 'HIGH_LIMITED',\n 2: 'HIGH_MODERATE',\n 3: 'HIGH_EXTENSIVE',\n 4: 'MEDIUM_LIMITED',\n 5: 'MEDIUM_MODERATE',\n 6: 'MEDIUM_EXTENSIVE',\n 7: 'LOW_LIMITED',\n 8: 'LOW_MODERATE',\n 9: 'LOW_EXTENSIVE',\n}\n"],"mappings":"AAEA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,SAAA,UACA,EAAA,QAAA;AACF,GAAA,CAAA,CAAA,GAIa,IAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKa,IAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEa,IAA4B;AAAA,EACvC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,cAAc;AAChB,GAEa,IAA6B;AAAA,EACxC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL,GAEa,IAAiC;AAAA,EAC5C,SAAS;AAAA,EACT,cAAc;AAAA,EACd,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,eAAe;AACjB,GAEa,IAAkC;AAAA,EAC7C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL"}
|
|
@@ -8,3 +8,9 @@ export declare enum RecurrenceTypes {
|
|
|
8
8
|
EveryOtherQuarter = 6,
|
|
9
9
|
EveryYear = 7
|
|
10
10
|
}
|
|
11
|
+
export declare const MainClassGuids: {
|
|
12
|
+
readonly PAYROLL: "MNC-bfc102ab-d4c3-41a7-9cf6-fdbf2e1ed7ea";
|
|
13
|
+
readonly PAYROLL_QA: "MNC-cc857751-2758-4f50-bdfe-d1210f40a155";
|
|
14
|
+
};
|
|
15
|
+
export declare const ALLOWED_MERCHANTLESS_BILL_CATEGORIES: readonly [string, string, string, string, string, string, string];
|
|
16
|
+
export declare const ALLOWED_MERCHANTLESS_INCOME_MAIN_CLASSES: readonly ["MNC-bfc102ab-d4c3-41a7-9cf6-fdbf2e1ed7ea", "MNC-cc857751-2758-4f50-bdfe-d1210f40a155"];
|
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { CategoryGuids as L } from "./Category.es.js";
|
|
2
|
+
var v = /* @__PURE__ */ (function(E) {
|
|
3
|
+
return E[E.Unknown = 0] = "Unknown", E[E.EveryWeek = 1] = "EveryWeek", E[E.EveryOtherWeek = 2] = "EveryOtherWeek", E[E.EveryMonth = 3] = "EveryMonth", E[E.EveryOtherMonth = 4] = "EveryOtherMonth", E[E.EveryQuarter = 5] = "EveryQuarter", E[E.EveryOtherQuarter = 6] = "EveryOtherQuarter", E[E.EveryYear = 7] = "EveryYear", E;
|
|
4
|
+
})({}), O = {
|
|
5
|
+
PAYROLL: "MNC-bfc102ab-d4c3-41a7-9cf6-fdbf2e1ed7ea",
|
|
6
|
+
PAYROLL_QA: "MNC-cc857751-2758-4f50-bdfe-d1210f40a155"
|
|
7
|
+
}, a = [
|
|
8
|
+
L.MORTGAGE_RENT,
|
|
9
|
+
L.BILLS_AND_UTILITIES,
|
|
10
|
+
L.HOME_PHONE,
|
|
11
|
+
L.INTERNET,
|
|
12
|
+
L.MOBILE_PHONE,
|
|
13
|
+
L.TELEVISION,
|
|
14
|
+
L.UTILITIES
|
|
15
|
+
], A = [O.PAYROLL, O.PAYROLL_QA];
|
|
4
16
|
export {
|
|
17
|
+
a as ALLOWED_MERCHANTLESS_BILL_CATEGORIES,
|
|
18
|
+
A as ALLOWED_MERCHANTLESS_INCOME_MAIN_CLASSES,
|
|
19
|
+
O as MainClassGuids,
|
|
5
20
|
v as RecurrenceTypes
|
|
6
21
|
};
|
|
7
22
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeatingTransactions.es.js","names":[],"sources":["../../../src/core/constants/repeatingTransactions.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"repeatingTransactions.es.js","names":[],"sources":["../../../src/core/constants/repeatingTransactions.ts"],"sourcesContent":["import { CategoryGuids } from './Category'\n\nexport enum RecurrenceTypes {\n Unknown = 0,\n EveryWeek = 1,\n EveryOtherWeek = 2,\n EveryMonth = 3,\n EveryOtherMonth = 4,\n EveryQuarter = 5,\n EveryOtherQuarter = 6,\n EveryYear = 7,\n}\n\nexport const MainClassGuids = {\n PAYROLL: 'MNC-bfc102ab-d4c3-41a7-9cf6-fdbf2e1ed7ea',\n PAYROLL_QA: 'MNC-cc857751-2758-4f50-bdfe-d1210f40a155',\n} as const\n\nexport const ALLOWED_MERCHANTLESS_BILL_CATEGORIES = [\n CategoryGuids.MORTGAGE_RENT,\n CategoryGuids.BILLS_AND_UTILITIES,\n CategoryGuids.HOME_PHONE,\n CategoryGuids.INTERNET,\n CategoryGuids.MOBILE_PHONE,\n CategoryGuids.TELEVISION,\n CategoryGuids.UTILITIES,\n] as const\n\nexport const ALLOWED_MERCHANTLESS_INCOME_MAIN_CLASSES = [\n MainClassGuids.PAYROLL,\n MainClassGuids.PAYROLL_QA,\n] as const\n"],"mappings":";AAEA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,YAAA,CAAA,IAAA,aACA,EAAA,EAAA,iBAAA,CAAA,IAAA,kBACA,EAAA,EAAA,aAAA,CAAA,IAAA,cACA,EAAA,EAAA,kBAAA,CAAA,IAAA,mBACA,EAAA,EAAA,eAAA,CAAA,IAAA,gBACA,EAAA,EAAA,oBAAA,CAAA,IAAA,qBACA,EAAA,EAAA,YAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEa,IAAiB;AAAA,EAC5B,SAAS;AAAA,EACT,YAAY;AACd,GAEa,IAAuC;AAAA,EAClD,EAAc;AAAA,EACd,EAAc;AAAA,EACd,EAAc;AAAA,EACd,EAAc;AAAA,EACd,EAAc;AAAA,EACd,EAAc;AAAA,EACd,EAAc;AAChB,GAEa,IAA2C,CACtD,EAAe,SACf,EAAe,UACjB"}
|
|
@@ -15,6 +15,9 @@ export declare class HoldingStore {
|
|
|
15
15
|
[x: string]: number;
|
|
16
16
|
};
|
|
17
17
|
get visibleHoldings(): Holding[];
|
|
18
|
+
get hasAllocationData(): boolean;
|
|
19
|
+
get hasAnalysisData(): boolean;
|
|
20
|
+
get selectedInvestmentAccounts(): import('..').DetailedAccount[];
|
|
18
21
|
setHoldings: (holdings: Holding[]) => void;
|
|
19
22
|
setShowConnectionsWidget: (value: boolean) => void;
|
|
20
23
|
loadHoldings: () => Promise<void>;
|
|
@@ -1,60 +1,70 @@
|
|
|
1
|
-
import { HoldingApi as
|
|
1
|
+
import { HoldingApi as o } from "../api/HoldingApi.es.js";
|
|
2
2
|
import { AnalysisType as n } from "../constants/Investments.es.js";
|
|
3
|
-
import { analysisChartData as a, analysisDetailsData as r, mapDataToPercentageGrid as
|
|
4
|
-
import { makeAutoObservable as
|
|
5
|
-
var
|
|
3
|
+
import { analysisChartData as a, analysisDetailsData as l, holdingHasAllocationData as r, holdingHasStyleData as d, mapDataToPercentageGrid as h } from "../utils/InvestmentUtil.es.js";
|
|
4
|
+
import { makeAutoObservable as c, runInAction as g } from "mobx";
|
|
5
|
+
var m = class {
|
|
6
6
|
analysisType = n.Stocks;
|
|
7
|
-
api = new
|
|
7
|
+
api = new o("/", "");
|
|
8
8
|
holdings = [];
|
|
9
9
|
holdingsLoaded = !1;
|
|
10
10
|
globalStore;
|
|
11
11
|
showConnectionsWidget = !1;
|
|
12
|
-
constructor(
|
|
13
|
-
this.globalStore =
|
|
12
|
+
constructor(s) {
|
|
13
|
+
this.globalStore = s, this.api = new o(s.endpoint, s.sessionToken, s.onError), c(this);
|
|
14
14
|
}
|
|
15
15
|
get analysisChartData() {
|
|
16
|
-
return
|
|
16
|
+
return h(a(this.visibleHoldings), this.analysisType);
|
|
17
17
|
}
|
|
18
18
|
get analysisDetails() {
|
|
19
|
-
return
|
|
19
|
+
return l(this.visibleHoldings)[this.analysisType] || {};
|
|
20
20
|
}
|
|
21
21
|
get visibleHoldings() {
|
|
22
|
-
return this.holdings.filter((
|
|
22
|
+
return this.holdings.filter((s) => this.globalStore.globalUiStore.selectedAccountGuids.includes(s.account_guid));
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
this.
|
|
24
|
+
get hasAllocationData() {
|
|
25
|
+
return this.visibleHoldings.some(r) ? !0 : this.selectedInvestmentAccounts.some((s) => (s.cash_balance ?? 0) > 0);
|
|
26
|
+
}
|
|
27
|
+
get hasAnalysisData() {
|
|
28
|
+
return this.visibleHoldings.some(d);
|
|
29
|
+
}
|
|
30
|
+
get selectedInvestmentAccounts() {
|
|
31
|
+
const { selectedAccountGuids: s } = this.globalStore.globalUiStore;
|
|
32
|
+
return this.globalStore.accountStore.visibleInvestmentAccounts.filter((t) => s.includes(t.guid));
|
|
33
|
+
}
|
|
34
|
+
setHoldings = (s) => {
|
|
35
|
+
this.holdings = s, this.holdingsLoaded = !0;
|
|
26
36
|
};
|
|
27
|
-
setShowConnectionsWidget = (
|
|
28
|
-
this.showConnectionsWidget =
|
|
37
|
+
setShowConnectionsWidget = (s) => {
|
|
38
|
+
this.showConnectionsWidget = s;
|
|
29
39
|
};
|
|
30
40
|
loadHoldings = async () => {
|
|
31
41
|
try {
|
|
32
|
-
const
|
|
33
|
-
this.setHoldings(
|
|
34
|
-
} catch (
|
|
35
|
-
console.error("Error occurred while getting holdings:",
|
|
42
|
+
const s = await this.api.getHoldings();
|
|
43
|
+
this.setHoldings(s);
|
|
44
|
+
} catch (s) {
|
|
45
|
+
console.error("Error occurred while getting holdings:", s), this.globalStore.captureException(s, { store: "HoldingStore" });
|
|
36
46
|
}
|
|
37
47
|
};
|
|
38
|
-
setAnalysisType = (
|
|
39
|
-
this.analysisType =
|
|
48
|
+
setAnalysisType = (s) => {
|
|
49
|
+
this.analysisType = s;
|
|
40
50
|
};
|
|
41
|
-
updateHoldings = async (
|
|
51
|
+
updateHoldings = async (s) => {
|
|
42
52
|
this.holdingsLoaded = !1;
|
|
43
53
|
try {
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
this.holdings =
|
|
54
|
+
const t = await this.api.updateHoldings(s), e = this.holdings.findIndex(({ guid: i }) => i === s.guid);
|
|
55
|
+
if (e >= 0) {
|
|
56
|
+
const i = [...this.holdings];
|
|
57
|
+
i[e] = t, g(() => {
|
|
58
|
+
this.holdings = i, this.holdingsLoaded = !0;
|
|
49
59
|
});
|
|
50
60
|
}
|
|
51
|
-
} catch (
|
|
52
|
-
console.error("Error occurred while updating holding:",
|
|
61
|
+
} catch (t) {
|
|
62
|
+
console.error("Error occurred while updating holding:", t), this.globalStore.captureException(t, { store: "HoldingStore" });
|
|
53
63
|
}
|
|
54
64
|
};
|
|
55
65
|
};
|
|
56
66
|
export {
|
|
57
|
-
|
|
67
|
+
m as HoldingStore
|
|
58
68
|
};
|
|
59
69
|
|
|
60
70
|
//# sourceMappingURL=HoldingStore.es.js.map
|
|
@@ -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 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 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 console.error('Error occurred while getting holdings:', error)\n this.globalStore.captureException(error, { store: 'HoldingStore' })\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 console.error('Error occurred while updating holding:', error)\n this.globalStore.captureException(error, { store: 'HoldingStore' })\n }\n }\n}\n"],"mappings":";;;;
|
|
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 console.error('Error occurred while getting holdings:', error)\n this.globalStore.captureException(error, { store: 'HoldingStore' })\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 console.error('Error occurred while updating holding:', error)\n this.globalStore.captureException(error, { store: 'HoldingStore' })\n }\n }\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,cAAQ,MAAM,0CAA0C,CAAK,GAC7D,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;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,cAAQ,MAAM,0CAA0C,CAAK,GAC7D,KAAK,YAAY,iBAAiB,GAAO,EAAE,OAAO,eAAe,CAAC;AAAA,IACpE;AAAA,EACF;AACF"}
|
|
@@ -30,7 +30,9 @@ export declare enum RepeatingType {
|
|
|
30
30
|
export interface RepeatingTransaction {
|
|
31
31
|
guid: string;
|
|
32
32
|
account_guid: string;
|
|
33
|
+
category_guid?: string | null;
|
|
33
34
|
created_by: number;
|
|
35
|
+
main_class_guid?: string | null;
|
|
34
36
|
member_guid: string;
|
|
35
37
|
merchant_guid?: string | null;
|
|
36
38
|
user_guid: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RepeatingTransaction.es.js","names":[],"sources":["../../../src/core/types/RepeatingTransaction.ts"],"sourcesContent":["import { Account } from './Account'\nimport { Transaction, TransactionType } from './Transaction'\n\nexport enum Frequency {\n Unknown = 0,\n EveryWeek = 1,\n EveryOtherWeek = 2,\n EveryMonth = 3,\n EveryOtherMonth = 4,\n EveryQuarter = 5,\n EveryOtherQuarter = 6,\n EveryYear = 7,\n TwiceAMonth = 8,\n}\n\nexport enum RecurrenceStatus {\n Paid = 0,\n Missed = 1,\n Upcoming = 2,\n}\n\nexport enum RecurrenceType {\n Expense = 0,\n Income = 1,\n}\n\nexport enum RepeatingType {\n Unknown = 0,\n Subscription = 1,\n Bill = 2,\n Income = 3,\n Transfer = 4,\n}\n\nexport interface RepeatingTransaction {\n // API fields\n guid: string\n account_guid: string\n created_by: number\n member_guid: string\n merchant_guid?: string | null\n user_guid: string\n description: string\n amount: number\n predicted_occurs_on: string\n transaction_type: TransactionType\n recurrence_type: Frequency\n recurrence_day: number\n repeating_transaction_type: RepeatingType\n second_recurrence_day?: number\n\n // UI fields\n account?: Account\n transactions: Transaction[]\n}\n\nexport interface Recurrence {\n accountGuid: string\n amount: number\n categoryGuid: string\n expectedDate: Date\n frequency: Frequency\n institutionGuid: string\n institutionName: string\n merchantGuid?: string | null\n name: string\n occurredOnDate?: Date\n recurrenceDay: number\n repeatingTransactionGuid: string\n secondRecurrenceDay?: number\n status: RecurrenceStatus\n type: RecurrenceType\n transaction?: Transaction\n}\n"],"mappings":"AAGA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,YAAA,CAAA,IAAA,aACA,EAAA,EAAA,iBAAA,CAAA,IAAA,kBACA,EAAA,EAAA,aAAA,CAAA,IAAA,cACA,EAAA,EAAA,kBAAA,CAAA,IAAA,mBACA,EAAA,EAAA,eAAA,CAAA,IAAA,gBACA,EAAA,EAAA,oBAAA,CAAA,IAAA,qBACA,EAAA,EAAA,YAAA,CAAA,IAAA,aACA,EAAA,EAAA,cAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,OAAA,CAAA,IAAA,QACA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,WAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,SAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,eAAA,CAAA,IAAA,gBACA,EAAA,EAAA,OAAA,CAAA,IAAA,QACA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,WAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"RepeatingTransaction.es.js","names":[],"sources":["../../../src/core/types/RepeatingTransaction.ts"],"sourcesContent":["import { Account } from './Account'\nimport { Transaction, TransactionType } from './Transaction'\n\nexport enum Frequency {\n Unknown = 0,\n EveryWeek = 1,\n EveryOtherWeek = 2,\n EveryMonth = 3,\n EveryOtherMonth = 4,\n EveryQuarter = 5,\n EveryOtherQuarter = 6,\n EveryYear = 7,\n TwiceAMonth = 8,\n}\n\nexport enum RecurrenceStatus {\n Paid = 0,\n Missed = 1,\n Upcoming = 2,\n}\n\nexport enum RecurrenceType {\n Expense = 0,\n Income = 1,\n}\n\nexport enum RepeatingType {\n Unknown = 0,\n Subscription = 1,\n Bill = 2,\n Income = 3,\n Transfer = 4,\n}\n\nexport interface RepeatingTransaction {\n // API fields\n guid: string\n account_guid: string\n category_guid?: string | null\n created_by: number\n main_class_guid?: string | null\n member_guid: string\n merchant_guid?: string | null\n user_guid: string\n description: string\n amount: number\n predicted_occurs_on: string\n transaction_type: TransactionType\n recurrence_type: Frequency\n recurrence_day: number\n repeating_transaction_type: RepeatingType\n second_recurrence_day?: number\n\n // UI fields\n account?: Account\n transactions: Transaction[]\n}\n\nexport interface Recurrence {\n accountGuid: string\n amount: number\n categoryGuid: string\n expectedDate: Date\n frequency: Frequency\n institutionGuid: string\n institutionName: string\n merchantGuid?: string | null\n name: string\n occurredOnDate?: Date\n recurrenceDay: number\n repeatingTransactionGuid: string\n secondRecurrenceDay?: number\n status: RecurrenceStatus\n type: RecurrenceType\n transaction?: Transaction\n}\n"],"mappings":"AAGA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,YAAA,CAAA,IAAA,aACA,EAAA,EAAA,iBAAA,CAAA,IAAA,kBACA,EAAA,EAAA,aAAA,CAAA,IAAA,cACA,EAAA,EAAA,kBAAA,CAAA,IAAA,mBACA,EAAA,EAAA,eAAA,CAAA,IAAA,gBACA,EAAA,EAAA,oBAAA,CAAA,IAAA,qBACA,EAAA,EAAA,YAAA,CAAA,IAAA,aACA,EAAA,EAAA,cAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,OAAA,CAAA,IAAA,QACA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,WAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,SAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,UAAA,CAAA,IAAA,WACA,EAAA,EAAA,eAAA,CAAA,IAAA,gBACA,EAAA,EAAA,OAAA,CAAA,IAAA,QACA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,WAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.es.js","names":[],"sources":["../../../src/core/types/Transaction.ts"],"sourcesContent":["export interface Transaction {\n guid: string\n account_guid: string\n amount: number\n attachment_guid?: string | null\n category_guid?: string\n check_number?: string | null\n currency_code: string | null\n date: number\n description: string\n duplicate: boolean\n external_guid?: string | null\n feed_attachment_guid?: string | null\n feed_description: string\n feed_localized_description?: string | null\n feed_posted_date?: number | null\n feed_status: TransactionStatus | null\n feed_transaction_date: number | null\n flags?: number | null\n has_been_split: boolean\n has_been_viewed: boolean\n is_cleared: boolean\n is_flagged: boolean\n is_hidden: boolean\n is_international?: boolean | null\n is_manual: boolean\n is_personal: boolean\n is_reimbursable: boolean\n is_subscription: boolean\n is_void: boolean\n localized_description?: string | null\n localized_memo?: string | null\n memo?: string | null\n metadata?: string | null\n merchant_guid?: string | null\n parent_guid?: string | null\n posted_date?: number | null\n reference?: string | null\n revision: number\n repeating_transaction_guid?: string | null\n scheduled_payment_guid?: string | null\n top_level_category_guid?: string\n transaction_type: TransactionType\n user_date?: number | null\n user_guid: string\n user_transaction_rule_guid?: string | null\n is_duplicate: boolean\n tags: string[]\n feed_transacted_at: number | null\n\n // Detailed Transaction fields\n account?: string\n accountIsClosed?: boolean\n accountIsHidden?: boolean\n category?: string\n isIncome?: boolean\n isPending?: boolean\n number?: string\n payee?: string\n}\n\nexport enum TransactionType {\n CREDIT = 1,\n DEBIT = 2,\n}\n\nexport enum TransactionStatus {\n POSTED = 1,\n PENDING = 2,\n}\n\nexport interface Tag {\n guid: string\n is_default_tag: boolean\n name: string\n user_guid: string\n}\n\nexport interface Tagging {\n guid: string\n user_guid: string\n tag_guid: string\n transaction_guid: string\n}\n\nexport interface TransactionRule {\n guid: string\n user_guid: string\n category_guid: string | null\n match_description: string\n description: string | null\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Transaction.es.js","names":[],"sources":["../../../src/core/types/Transaction.ts"],"sourcesContent":["export interface Transaction {\n guid: string\n account_guid: string\n amount: number\n attachment_guid?: string | null\n category_guid?: string\n check_number?: string | null\n currency_code: string | null\n date: number\n description: string\n duplicate: boolean\n external_guid?: string | null\n feed_attachment_guid?: string | null\n feed_description: string\n feed_localized_description?: string | null\n feed_posted_date?: number | null\n feed_status: TransactionStatus | null\n feed_transaction_date: number | null\n flags?: number | null\n has_been_split: boolean\n has_been_viewed: boolean\n is_cleared: boolean\n is_flagged: boolean\n is_hidden: boolean\n is_international?: boolean | null\n is_manual: boolean\n is_personal: boolean\n is_reimbursable: boolean\n is_subscription: boolean\n is_void: boolean\n localized_description?: string | null\n localized_memo?: string | null\n main_class_guid?: string | null\n memo?: string | null\n metadata?: string | null\n merchant_guid?: string | null\n parent_guid?: string | null\n posted_date?: number | null\n reference?: string | null\n revision: number\n repeating_transaction_guid?: string | null\n scheduled_payment_guid?: string | null\n top_level_category_guid?: string\n transaction_type: TransactionType\n user_date?: number | null\n user_guid: string\n user_transaction_rule_guid?: string | null\n is_duplicate: boolean\n tags: string[]\n feed_transacted_at: number | null\n\n // Detailed Transaction fields\n account?: string\n accountIsClosed?: boolean\n accountIsHidden?: boolean\n category?: string\n isIncome?: boolean\n isPending?: boolean\n number?: string\n payee?: string\n}\n\nexport enum TransactionType {\n CREDIT = 1,\n DEBIT = 2,\n}\n\nexport enum TransactionStatus {\n POSTED = 1,\n PENDING = 2,\n}\n\nexport interface Tag {\n guid: string\n is_default_tag: boolean\n name: string\n user_guid: string\n}\n\nexport interface Tagging {\n guid: string\n user_guid: string\n tag_guid: string\n transaction_guid: string\n}\n\nexport interface TransactionRule {\n guid: string\n user_guid: string\n category_guid: string | null\n match_description: string\n description: string | null\n}\n"],"mappings":"AA8DA,IAAY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,QAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA,GAEY,IAAL,0BAAA,GAAA;AACL,SAAA,EAAA,EAAA,SAAA,CAAA,IAAA,UACA,EAAA,EAAA,UAAA,CAAA,IAAA;AACF,GAAA,CAAA,CAAA"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Holding } from '../types';
|
|
2
2
|
import { AnalysisType } from '../constants/Investments';
|
|
3
3
|
type WeightMap = Record<string, number>;
|
|
4
|
+
export declare const isMeaningfulNumber: (value: unknown) => boolean;
|
|
5
|
+
export declare const isValidClassification: (value: unknown) => boolean;
|
|
6
|
+
export declare const holdingHasStyleData: (holding: Holding) => boolean;
|
|
7
|
+
export declare const holdingHasAllocationData: (holding: Holding) => boolean;
|
|
4
8
|
export declare const createGroups: (classificationObj: Record<number, string>, groupSize?: number) => string[][];
|
|
5
9
|
export declare const bondGroups: string[][];
|
|
6
10
|
export declare const stockGroups: string[][];
|
|
@@ -1,80 +1,93 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
var
|
|
4
|
-
const
|
|
5
|
-
|
|
1
|
+
import { ALLOCATION_KEYS as V, AnalysisType as k, EquityClassificationTypes as A, EquityClassificationValues as m, FixedIncomeClassificationTypes as G, FixedIncomeClassificationValues as f, STYLE_WEIGHT_KEYS as T } from "../constants/Investments.es.js";
|
|
2
|
+
import W from "numeral";
|
|
3
|
+
var S = 80, x = 120, h = (e) => e > S && e < x, C = (e) => {
|
|
4
|
+
const t = Number(e);
|
|
5
|
+
return Number.isFinite(t) && t !== 0;
|
|
6
|
+
}, d = (e) => {
|
|
7
|
+
const t = Number(e);
|
|
8
|
+
return Number.isFinite(t) && t >= 1 && t <= 9;
|
|
9
|
+
}, F = (e) => {
|
|
10
|
+
const t = T.reduce((r, s) => r + (Number(e[s]) || 0), 0);
|
|
11
|
+
return h(t) || t === 0 && (d(e.equity_classification) || d(e.fixed_income_classification));
|
|
12
|
+
}, q = (e) => V.some((t) => C(e[t])), E = (e, t = 3) => {
|
|
13
|
+
const r = Object.keys(e).map(Number).filter((a) => a !== 0).sort((a, i) => a - i), s = [];
|
|
14
|
+
for (let a = 0; a < r.length; a += t) s.push(r.slice(a, a + t).map((i) => e[i]));
|
|
6
15
|
return s;
|
|
7
|
-
},
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const l = i(
|
|
11
|
-
return Object.keys(l).forEach((_) =>
|
|
16
|
+
}, I = E(f), D = E(m), K = (e) => {
|
|
17
|
+
const t = p(e, w), r = p(e, y), s = (a, i) => {
|
|
18
|
+
const o = a.reduce((n, c) => n + N(c), 0), u = a.reduce((n, c) => {
|
|
19
|
+
const l = i(c);
|
|
20
|
+
return Object.keys(l).forEach((_) => n[_] = (n[_] || 0) + l[_]), n;
|
|
12
21
|
}, {});
|
|
13
|
-
return Object.fromEntries(Object.entries(u).map(([
|
|
22
|
+
return Object.fromEntries(Object.entries(u).map(([n, c]) => [n, c / o * 100]));
|
|
14
23
|
};
|
|
15
24
|
return {
|
|
16
|
-
stocks: s(
|
|
17
|
-
bonds: s(r,
|
|
25
|
+
stocks: s(t, L),
|
|
26
|
+
bonds: s(r, b)
|
|
18
27
|
};
|
|
19
|
-
},
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
return Object.keys(
|
|
23
|
-
u[l] = (u[l] || 0) + (
|
|
28
|
+
}, U = (e) => {
|
|
29
|
+
const t = e.filter((a) => !isNaN(a.equity_classification)), r = e.filter((a) => !isNaN(a.fixed_income_classification)), s = (a, i, o) => a.reduce((u, n) => {
|
|
30
|
+
const c = i(n);
|
|
31
|
+
return Object.keys(o).forEach((l) => {
|
|
32
|
+
u[l] = (u[l] || 0) + (c[l] || 0);
|
|
24
33
|
}), u;
|
|
25
34
|
}, {});
|
|
26
35
|
return {
|
|
27
|
-
stocks: s(
|
|
28
|
-
bonds: s(r,
|
|
36
|
+
stocks: s(t, L, A),
|
|
37
|
+
bonds: s(r, b, G)
|
|
29
38
|
};
|
|
30
|
-
},
|
|
31
|
-
const
|
|
32
|
-
return { [f[
|
|
33
|
-
},
|
|
34
|
-
const { large_core_weight:
|
|
35
|
-
LARGE_CORE:
|
|
39
|
+
}, H = (e, t) => Object.fromEntries(Object.entries(e).map(([r, s]) => [r, s * t / 100])), b = (e) => O(e, y, f), y = (e) => {
|
|
40
|
+
const t = e.fixed_income_classification;
|
|
41
|
+
return { [f[t]]: 100 };
|
|
42
|
+
}, L = (e) => O(e, w, m), w = (e) => {
|
|
43
|
+
const { large_core_weight: t, large_growth_weight: r, large_value_weight: s, mid_core_weight: a, mid_growth_weight: i, mid_value_weight: o, small_core_weight: u, small_growth_weight: n, small_value_weight: c, unknown_weight: l, equity_classification: _ } = e, g = {
|
|
44
|
+
LARGE_CORE: t ?? 0,
|
|
36
45
|
LARGE_GROWTH: r ?? 0,
|
|
37
46
|
LARGE_VALUE: s ?? 0,
|
|
38
|
-
MID_CORE:
|
|
47
|
+
MID_CORE: a ?? 0,
|
|
39
48
|
MID_GROWTH: i ?? 0,
|
|
40
|
-
MID_VALUE:
|
|
49
|
+
MID_VALUE: o ?? 0,
|
|
41
50
|
SMALL_CORE: u ?? 0,
|
|
42
|
-
SMALL_GROWTH:
|
|
43
|
-
SMALL_VALUE:
|
|
51
|
+
SMALL_GROWTH: n ?? 0,
|
|
52
|
+
SMALL_VALUE: c ?? 0,
|
|
44
53
|
UNKNOWN: l ?? 0
|
|
45
54
|
};
|
|
46
|
-
return g
|
|
47
|
-
},
|
|
48
|
-
const s =
|
|
49
|
-
if (
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
52
|
-
console.error(`Invalid classification key: ${
|
|
55
|
+
return v(g) === 0 && _ !== void 0 ? { [m[_]]: 100 } : g;
|
|
56
|
+
}, O = (e, t, r) => {
|
|
57
|
+
const s = t(e), a = N(e), i = H(s, a);
|
|
58
|
+
if (v(i) === 0) {
|
|
59
|
+
const o = String(e.equity_classification ?? e.fixed_income_classification);
|
|
60
|
+
if (o in r) return { [r[o]]: a };
|
|
61
|
+
console.error(`Invalid classification key: ${o}`);
|
|
53
62
|
}
|
|
54
63
|
return i;
|
|
55
|
-
},
|
|
56
|
-
const s =
|
|
57
|
-
return
|
|
58
|
-
}),
|
|
59
|
-
const r =
|
|
60
|
-
return !s || Object.keys(s).length === 0 ? r.map((
|
|
61
|
-
},
|
|
64
|
+
}, Y = (e) => e.split("_").map((t) => t.charAt(0).toUpperCase() + t.slice(1).toLowerCase()).join(" "), j = (e) => e >= 1 ? `${W(e).format("0")}%` : "< 1%", N = (e) => e.calculated_market_value ?? e.market_value, p = (e, t) => e.filter((r) => {
|
|
65
|
+
const s = t(r);
|
|
66
|
+
return h(v(s));
|
|
67
|
+
}), B = (e, t) => {
|
|
68
|
+
const r = t === k.Stocks ? D : I, s = e[t];
|
|
69
|
+
return !s || Object.keys(s).length === 0 ? r.map((a) => a.map(() => "0%")) : r.map((a) => a.map((i) => j(s[i] ?? 0)));
|
|
70
|
+
}, v = (e) => Object.values(e).reduce((t, r) => t + r, 0);
|
|
62
71
|
export {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
K as analysisChartData,
|
|
73
|
+
U as analysisDetailsData,
|
|
74
|
+
I as bondGroups,
|
|
75
|
+
H as calculateWeightedValue,
|
|
76
|
+
E as createGroups,
|
|
77
|
+
y as extractBondWeight,
|
|
78
|
+
w as extractStockWeight,
|
|
79
|
+
O as extractValueFromWeight,
|
|
80
|
+
Y as formatKey,
|
|
81
|
+
j as formatPercent,
|
|
82
|
+
N as getHoldingValue,
|
|
74
83
|
p as getValidHoldings,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
84
|
+
q as holdingHasAllocationData,
|
|
85
|
+
F as holdingHasStyleData,
|
|
86
|
+
C as isMeaningfulNumber,
|
|
87
|
+
d as isValidClassification,
|
|
88
|
+
B as mapDataToPercentageGrid,
|
|
89
|
+
D as stockGroups,
|
|
90
|
+
v as sumValues
|
|
78
91
|
};
|
|
79
92
|
|
|
80
93
|
//# sourceMappingURL=InvestmentUtil.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvestmentUtil.es.js","names":[],"sources":["../../../src/core/utils/InvestmentUtil.ts"],"sourcesContent":["import numeral from 'numeral'\n\nimport type { Holding } from '../types'\n\nimport {\n AnalysisType,\n EquityClassificationTypes,\n EquityClassificationValues,\n FixedIncomeClassificationTypes,\n FixedIncomeClassificationValues,\n} from '../constants/Investments'\n\ntype WeightMap = Record<string, number>\n\nexport const createGroups = (classificationObj: Record<number, string>, groupSize = 3) => {\n const keys = Object.keys(classificationObj)\n .map(Number)\n .filter((k) => k !== 0)\n .sort((a, b) => a - b)\n\n const groups = []\n for (let i = 0; i < keys.length; i += groupSize) {\n groups.push(keys.slice(i, i + groupSize).map((key) => classificationObj[key]))\n }\n return groups\n}\n\nexport const bondGroups = createGroups(FixedIncomeClassificationValues)\nexport const stockGroups = createGroups(EquityClassificationValues)\n\nexport const analysisChartData = (holdings: Holding[]) => {\n const stocks = getValidHoldings(holdings, extractStockWeight)\n const bonds = getValidHoldings(holdings, extractBondWeight)\n\n const processGroupData = (group: Holding[], extractValueFn: (holding: Holding) => WeightMap) => {\n const totalValue = group.reduce((acc, holding) => acc + getHoldingValue(holding), 0)\n const groupValues = group.reduce((acc, holding) => {\n const value = extractValueFn(holding)\n Object.keys(value).forEach((key) => (acc[key] = (acc[key] || 0) + value[key]))\n return acc\n }, {} as WeightMap)\n\n return Object.fromEntries(\n Object.entries(groupValues).map(([key, value]) => [key, (value / totalValue) * 100]),\n )\n }\n\n const data = {\n stocks: processGroupData(stocks, extractStockValueFromWeight),\n bonds: processGroupData(bonds, extractBondValueFromWeight),\n }\n\n return data\n}\n\nexport const analysisDetailsData = (holdings: Holding[]) => {\n const stocks = holdings.filter((holding) => !isNaN(holding.equity_classification))\n const bonds = holdings.filter((holding) => !isNaN(holding.fixed_income_classification))\n\n const aggregateValues = (\n holdings: Holding[],\n extractValueFn: (holding: Holding) => WeightMap,\n classificationTypes: Record<string, number>,\n ) => {\n return holdings.reduce((acc, holding) => {\n const values = extractValueFn(holding)\n Object.keys(classificationTypes).forEach((sector) => {\n acc[sector] = (acc[sector] || 0) + (values[sector] || 0)\n })\n return acc\n }, {} as WeightMap)\n }\n\n return {\n stocks: aggregateValues(stocks, extractStockValueFromWeight, EquityClassificationTypes),\n bonds: aggregateValues(bonds, extractBondValueFromWeight, FixedIncomeClassificationTypes),\n }\n}\n\nexport const calculateWeightedValue = (weights: WeightMap, value: number): WeightMap => {\n return Object.fromEntries(\n Object.entries(weights).map(([key, weight]) => [key, (weight * value) / 100]),\n )\n}\n\nconst extractBondValueFromWeight = (bond: Holding) =>\n extractValueFromWeight(bond, extractBondWeight, FixedIncomeClassificationValues)\n\nexport const extractBondWeight = (bond: Holding): WeightMap => {\n const classificationKey = bond.fixed_income_classification\n return {\n [FixedIncomeClassificationValues[\n classificationKey as keyof typeof FixedIncomeClassificationValues\n ]]: 100,\n }\n}\n\nconst extractStockValueFromWeight = (stock: Holding) =>\n extractValueFromWeight(stock, extractStockWeight, EquityClassificationValues)\n\nexport const extractStockWeight = (stock: Holding): WeightMap => {\n const {\n large_core_weight,\n large_growth_weight,\n large_value_weight,\n mid_core_weight,\n mid_growth_weight,\n mid_value_weight,\n small_core_weight,\n small_growth_weight,\n small_value_weight,\n unknown_weight,\n equity_classification,\n } = stock\n\n const data: WeightMap = {\n LARGE_CORE: large_core_weight ?? 0,\n LARGE_GROWTH: large_growth_weight ?? 0,\n LARGE_VALUE: large_value_weight ?? 0,\n MID_CORE: mid_core_weight ?? 0,\n MID_GROWTH: mid_growth_weight ?? 0,\n MID_VALUE: mid_value_weight ?? 0,\n SMALL_CORE: small_core_weight ?? 0,\n SMALL_GROWTH: small_growth_weight ?? 0,\n SMALL_VALUE: small_value_weight ?? 0,\n UNKNOWN: unknown_weight ?? 0,\n }\n\n if (sumValues(data) === 0 && equity_classification !== undefined) {\n const key =\n EquityClassificationValues[equity_classification as keyof typeof EquityClassificationValues]\n return { [key]: 100 }\n }\n\n return data\n}\n\nexport const extractValueFromWeight = (\n holding: Holding,\n extractWeightFn: (h: Holding) => WeightMap,\n classificationValues: Record<string, string>,\n): WeightMap => {\n const weights = extractWeightFn(holding)\n const value = getHoldingValue(holding)\n const weightedValues = calculateWeightedValue(weights, value)\n\n if (sumValues(weightedValues) === 0) {\n const classificationKey = String(\n holding.equity_classification ?? holding.fixed_income_classification,\n )\n\n if (classificationKey in classificationValues) {\n return { [classificationValues[classificationKey]]: value }\n } else {\n console.error(`Invalid classification key: ${classificationKey}`)\n }\n }\n\n return weightedValues\n}\n\nexport const formatKey = (key: string): string =>\n key\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n\nexport const formatPercent = (value: number): string =>\n value >= 1 ? `${numeral(value).format('0')}%` : '< 1%'\n\nexport const getHoldingValue = (holding: Holding): number =>\n holding.calculated_market_value ?? holding.market_value\n\nexport const getValidHoldings = (\n holdings: Holding[],\n extractWeightFn: (holding: Holding) => WeightMap,\n): Holding[] => {\n return holdings.filter((holding) => {\n const weight = extractWeightFn(holding)\n const total = sumValues(weight)\n return total > 80 && total < 120\n })\n}\n\nexport const mapDataToPercentageGrid = (\n data: Record<AnalysisType, Record<string, number>>,\n analysisType: AnalysisType,\n): string[][] => {\n const groups = analysisType === AnalysisType.Stocks ? stockGroups : bondGroups\n\n const selected = data[analysisType]\n if (!selected || Object.keys(selected).length === 0)\n return groups.map((group) => group.map(() => '0%'))\n\n return groups.map((group) => group.map((key) => formatPercent(selected[key] ?? 0)))\n}\n\nexport const sumValues = (obj: WeightMap): number =>\n Object.values(obj).reduce((acc, val) => acc + val, 0)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InvestmentUtil.es.js","names":[],"sources":["../../../src/core/utils/InvestmentUtil.ts"],"sourcesContent":["import numeral from 'numeral'\n\nimport type { Holding } from '../types'\n\nimport {\n ALLOCATION_KEYS,\n AnalysisType,\n EquityClassificationTypes,\n EquityClassificationValues,\n FixedIncomeClassificationTypes,\n FixedIncomeClassificationValues,\n STYLE_WEIGHT_KEYS,\n} from '../constants/Investments'\n\ntype WeightMap = Record<string, number>\n\n// The render band getValidHoldings keeps; the analysis gate reuses it so the\n// tab never enables onto an all-zero grid.\nconst STYLE_WEIGHT_MIN = 80\nconst STYLE_WEIGHT_MAX = 120\nconst isInStyleWeightBand = (total: number): boolean =>\n total > STYLE_WEIGHT_MIN && total < STYLE_WEIGHT_MAX\n\n// Coerces so a stringified number counts; null/\"\"/\"0\"/NaN/0 all mean \"no data\".\nexport const isMeaningfulNumber = (value: unknown): boolean => {\n const n = Number(value)\n return Number.isFinite(n) && n !== 0\n}\n\n// Classification 0 is UNKNOWN; only 1..9 represent real data.\nexport const isValidClassification = (value: unknown): boolean => {\n const n = Number(value)\n return Number.isFinite(n) && n >= 1 && n <= 9\n}\n\n// Classification only counts when style weights sum to 0, matching\n// extractWeight's fallback — otherwise a partial (out-of-band) total that\n// getValidHoldings drops would wrongly enable the tab onto an empty grid.\nexport const holdingHasStyleData = (holding: Holding): boolean => {\n const styleTotal = STYLE_WEIGHT_KEYS.reduce((sum, key) => sum + (Number(holding[key]) || 0), 0)\n return (\n isInStyleWeightBand(styleTotal) ||\n (styleTotal === 0 &&\n (isValidClassification(holding.equity_classification) ||\n isValidClassification(holding.fixed_income_classification)))\n )\n}\n\nexport const holdingHasAllocationData = (holding: Holding): boolean =>\n ALLOCATION_KEYS.some((key) => isMeaningfulNumber(holding[key]))\n\nexport const createGroups = (classificationObj: Record<number, string>, groupSize = 3) => {\n const keys = Object.keys(classificationObj)\n .map(Number)\n .filter((k) => k !== 0)\n .sort((a, b) => a - b)\n\n const groups = []\n for (let i = 0; i < keys.length; i += groupSize) {\n groups.push(keys.slice(i, i + groupSize).map((key) => classificationObj[key]))\n }\n return groups\n}\n\nexport const bondGroups = createGroups(FixedIncomeClassificationValues)\nexport const stockGroups = createGroups(EquityClassificationValues)\n\nexport const analysisChartData = (holdings: Holding[]) => {\n const stocks = getValidHoldings(holdings, extractStockWeight)\n const bonds = getValidHoldings(holdings, extractBondWeight)\n\n const processGroupData = (group: Holding[], extractValueFn: (holding: Holding) => WeightMap) => {\n const totalValue = group.reduce((acc, holding) => acc + getHoldingValue(holding), 0)\n const groupValues = group.reduce((acc, holding) => {\n const value = extractValueFn(holding)\n Object.keys(value).forEach((key) => (acc[key] = (acc[key] || 0) + value[key]))\n return acc\n }, {} as WeightMap)\n\n return Object.fromEntries(\n Object.entries(groupValues).map(([key, value]) => [key, (value / totalValue) * 100]),\n )\n }\n\n const data = {\n stocks: processGroupData(stocks, extractStockValueFromWeight),\n bonds: processGroupData(bonds, extractBondValueFromWeight),\n }\n\n return data\n}\n\nexport const analysisDetailsData = (holdings: Holding[]) => {\n const stocks = holdings.filter((holding) => !isNaN(holding.equity_classification))\n const bonds = holdings.filter((holding) => !isNaN(holding.fixed_income_classification))\n\n const aggregateValues = (\n holdings: Holding[],\n extractValueFn: (holding: Holding) => WeightMap,\n classificationTypes: Record<string, number>,\n ) => {\n return holdings.reduce((acc, holding) => {\n const values = extractValueFn(holding)\n Object.keys(classificationTypes).forEach((sector) => {\n acc[sector] = (acc[sector] || 0) + (values[sector] || 0)\n })\n return acc\n }, {} as WeightMap)\n }\n\n return {\n stocks: aggregateValues(stocks, extractStockValueFromWeight, EquityClassificationTypes),\n bonds: aggregateValues(bonds, extractBondValueFromWeight, FixedIncomeClassificationTypes),\n }\n}\n\nexport const calculateWeightedValue = (weights: WeightMap, value: number): WeightMap => {\n return Object.fromEntries(\n Object.entries(weights).map(([key, weight]) => [key, (weight * value) / 100]),\n )\n}\n\nconst extractBondValueFromWeight = (bond: Holding) =>\n extractValueFromWeight(bond, extractBondWeight, FixedIncomeClassificationValues)\n\nexport const extractBondWeight = (bond: Holding): WeightMap => {\n const classificationKey = bond.fixed_income_classification\n return {\n [FixedIncomeClassificationValues[\n classificationKey as keyof typeof FixedIncomeClassificationValues\n ]]: 100,\n }\n}\n\nconst extractStockValueFromWeight = (stock: Holding) =>\n extractValueFromWeight(stock, extractStockWeight, EquityClassificationValues)\n\nexport const extractStockWeight = (stock: Holding): WeightMap => {\n const {\n large_core_weight,\n large_growth_weight,\n large_value_weight,\n mid_core_weight,\n mid_growth_weight,\n mid_value_weight,\n small_core_weight,\n small_growth_weight,\n small_value_weight,\n unknown_weight,\n equity_classification,\n } = stock\n\n const data: WeightMap = {\n LARGE_CORE: large_core_weight ?? 0,\n LARGE_GROWTH: large_growth_weight ?? 0,\n LARGE_VALUE: large_value_weight ?? 0,\n MID_CORE: mid_core_weight ?? 0,\n MID_GROWTH: mid_growth_weight ?? 0,\n MID_VALUE: mid_value_weight ?? 0,\n SMALL_CORE: small_core_weight ?? 0,\n SMALL_GROWTH: small_growth_weight ?? 0,\n SMALL_VALUE: small_value_weight ?? 0,\n UNKNOWN: unknown_weight ?? 0,\n }\n\n if (sumValues(data) === 0 && equity_classification !== undefined) {\n const key =\n EquityClassificationValues[equity_classification as keyof typeof EquityClassificationValues]\n return { [key]: 100 }\n }\n\n return data\n}\n\nexport const extractValueFromWeight = (\n holding: Holding,\n extractWeightFn: (h: Holding) => WeightMap,\n classificationValues: Record<string, string>,\n): WeightMap => {\n const weights = extractWeightFn(holding)\n const value = getHoldingValue(holding)\n const weightedValues = calculateWeightedValue(weights, value)\n\n if (sumValues(weightedValues) === 0) {\n const classificationKey = String(\n holding.equity_classification ?? holding.fixed_income_classification,\n )\n\n if (classificationKey in classificationValues) {\n return { [classificationValues[classificationKey]]: value }\n } else {\n console.error(`Invalid classification key: ${classificationKey}`)\n }\n }\n\n return weightedValues\n}\n\nexport const formatKey = (key: string): string =>\n key\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n\nexport const formatPercent = (value: number): string =>\n value >= 1 ? `${numeral(value).format('0')}%` : '< 1%'\n\nexport const getHoldingValue = (holding: Holding): number =>\n holding.calculated_market_value ?? holding.market_value\n\nexport const getValidHoldings = (\n holdings: Holding[],\n extractWeightFn: (holding: Holding) => WeightMap,\n): Holding[] => {\n return holdings.filter((holding) => {\n const weight = extractWeightFn(holding)\n return isInStyleWeightBand(sumValues(weight))\n })\n}\n\nexport const mapDataToPercentageGrid = (\n data: Record<AnalysisType, Record<string, number>>,\n analysisType: AnalysisType,\n): string[][] => {\n const groups = analysisType === AnalysisType.Stocks ? stockGroups : bondGroups\n\n const selected = data[analysisType]\n if (!selected || Object.keys(selected).length === 0)\n return groups.map((group) => group.map(() => '0%'))\n\n return groups.map((group) => group.map((key) => formatPercent(selected[key] ?? 0)))\n}\n\nexport const sumValues = (obj: WeightMap): number =>\n Object.values(obj).reduce((acc, val) => acc + val, 0)\n"],"mappings":";;AAkBA,IAAM,IAAmB,IACnB,IAAmB,KACnB,IAAA,CAAuB,MAC3B,IAAQ,KAAoB,IAAQ,GAGzB,IAAA,CAAsB,MAA4B;AAC7D,QAAM,IAAI,OAAO,CAAK;AACtB,SAAO,OAAO,SAAS,CAAC,KAAK,MAAM;AACrC,GAGa,IAAA,CAAyB,MAA4B;AAChE,QAAM,IAAI,OAAO,CAAK;AACtB,SAAO,OAAO,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK;AAC9C,GAKa,IAAA,CAAuB,MAA8B;AAChE,QAAM,IAAa,EAAkB,OAAA,CAAQ,GAAK,MAAQ,KAAO,OAAO,EAAQ,CAAA,CAAI,KAAK,IAAI,CAAC;AAC9F,SACE,EAAoB,CAAU,KAC7B,MAAe,MACb,EAAsB,EAAQ,qBAAqB,KAClD,EAAsB,EAAQ,2BAA2B;AAEjE,GAEa,IAAA,CAA4B,MACvC,EAAgB,KAAA,CAAM,MAAQ,EAAmB,EAAQ,CAAA,CAAI,CAAC,GAEnD,IAAA,CAAgB,GAA2C,IAAY,MAAM;AACxF,QAAM,IAAO,OAAO,KAAK,CAAiB,EACvC,IAAI,MAAM,EACV,OAAA,CAAQ,MAAM,MAAM,CAAC,EACrB,KAAA,CAAM,GAAG,MAAM,IAAI,CAAC,GAEjB,IAAS,CAAC;AAChB,WAAS,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK,EACpC,CAAA,EAAO,KAAK,EAAK,MAAM,GAAG,IAAI,CAAS,EAAE,IAAA,CAAK,MAAQ,EAAkB,CAAA,CAAI,CAAC;AAE/E,SAAO;AACT,GAEa,IAAa,EAAa,CAA+B,GACzD,IAAc,EAAa,CAA0B,GAErD,IAAA,CAAqB,MAAwB;AACxD,QAAM,IAAS,EAAiB,GAAU,CAAkB,GACtD,IAAQ,EAAiB,GAAU,CAAiB,GAEpD,IAAA,CAAoB,GAAkB,MAAoD;AAC9F,UAAM,IAAa,EAAM,OAAA,CAAQ,GAAK,MAAY,IAAM,EAAgB,CAAO,GAAG,CAAC,GAC7E,IAAc,EAAM,OAAA,CAAQ,GAAK,MAAY;AACjD,YAAM,IAAQ,EAAe,CAAO;AACpC,oBAAO,KAAK,CAAK,EAAE,QAAA,CAAS,MAAS,EAAI,CAAA,KAAQ,EAAI,CAAA,KAAQ,KAAK,EAAM,CAAA,CAAK,GACtE;AAAA,IACT,GAAG,CAAC,CAAc;AAElB,WAAO,OAAO,YACZ,OAAO,QAAQ,CAAW,EAAE,IAAA,CAAK,CAAC,GAAK,CAAA,MAAW,CAAC,GAAM,IAAQ,IAAc,GAAG,CAAC,CACrF;AAAA,EACF;AAOA,SAAO;AAAA,IAJL,QAAQ,EAAiB,GAAQ,CAA2B;AAAA,IAC5D,OAAO,EAAiB,GAAO,CAA0B;AAAA,EAGpD;AACT,GAEa,IAAA,CAAuB,MAAwB;AAC1D,QAAM,IAAS,EAAS,OAAA,CAAQ,MAAY,CAAC,MAAM,EAAQ,qBAAqB,CAAC,GAC3E,IAAQ,EAAS,OAAA,CAAQ,MAAY,CAAC,MAAM,EAAQ,2BAA2B,CAAC,GAEhF,IAAA,CACJ,GACA,GACA,MAEO,EAAS,OAAA,CAAQ,GAAK,MAAY;AACvC,UAAM,IAAS,EAAe,CAAO;AACrC,kBAAO,KAAK,CAAmB,EAAE,QAAA,CAAS,MAAW;AACnD,MAAA,EAAI,CAAA,KAAW,EAAI,CAAA,KAAW,MAAM,EAAO,CAAA,KAAW;AAAA,IACxD,CAAC,GACM;AAAA,EACT,GAAG,CAAC,CAAc;AAGpB,SAAO;AAAA,IACL,QAAQ,EAAgB,GAAQ,GAA6B,CAAyB;AAAA,IACtF,OAAO,EAAgB,GAAO,GAA4B,CAA8B;AAAA,EAC1F;AACF,GAEa,IAAA,CAA0B,GAAoB,MAClD,OAAO,YACZ,OAAO,QAAQ,CAAO,EAAE,IAAA,CAAK,CAAC,GAAK,CAAA,MAAY,CAAC,GAAM,IAAS,IAAS,GAAG,CAAC,CAC9E,GAGI,IAAA,CAA8B,MAClC,EAAuB,GAAM,GAAmB,CAA+B,GAEpE,IAAA,CAAqB,MAA6B;AAC7D,QAAM,IAAoB,EAAK;AAC/B,SAAO,EAAA,CACJ,EACC,CAAA,CAAA,GACE,IACN;AACF,GAEM,IAAA,CAA+B,MACnC,EAAuB,GAAO,GAAoB,CAA0B,GAEjE,IAAA,CAAsB,MAA8B;AAC/D,QAAM,EACJ,mBAAA,GACA,qBAAA,GACA,oBAAA,GACA,iBAAA,GACA,mBAAA,GACA,kBAAA,GACA,mBAAA,GACA,qBAAA,GACA,oBAAA,GACA,gBAAA,GACA,uBAAA,EAAA,IACE,GAEE,IAAkB;AAAA,IACtB,YAAY,KAAqB;AAAA,IACjC,cAAc,KAAuB;AAAA,IACrC,aAAa,KAAsB;AAAA,IACnC,UAAU,KAAmB;AAAA,IAC7B,YAAY,KAAqB;AAAA,IACjC,WAAW,KAAoB;AAAA,IAC/B,YAAY,KAAqB;AAAA,IACjC,cAAc,KAAuB;AAAA,IACrC,aAAa,KAAsB;AAAA,IACnC,SAAS,KAAkB;AAAA,EAC7B;AAEA,SAAI,EAAU,CAAI,MAAM,KAAK,MAA0B,SAG9C,EAAA,CADL,EAA2B,CAAA,CAAA,GACb,IAAI,IAGf;AACT,GAEa,IAAA,CACX,GACA,GACA,MACc;AACd,QAAM,IAAU,EAAgB,CAAO,GACjC,IAAQ,EAAgB,CAAO,GAC/B,IAAiB,EAAuB,GAAS,CAAK;AAE5D,MAAI,EAAU,CAAc,MAAM,GAAG;AACnC,UAAM,IAAoB,OACxB,EAAQ,yBAAyB,EAAQ,2BAC3C;AAEA,QAAI,KAAqB,EACvB,QAAO,EAAA,CAAG,EAAqB,CAAA,CAAA,GAAqB,EAAM;AAE1D,YAAQ,MAAM,+BAA+B,CAAA,EAAmB;AAAA,EAEpE;AAEA,SAAO;AACT,GAEa,IAAA,CAAa,MACxB,EACG,MAAM,GAAG,EACT,IAAA,CAAK,MAAS,EAAK,OAAO,CAAC,EAAE,YAAY,IAAI,EAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,GAAG,GAEA,IAAA,CAAiB,MAC5B,KAAS,IAAI,GAAG,EAAQ,CAAK,EAAE,OAAO,GAAG,CAAA,MAAO,QAErC,IAAA,CAAmB,MAC9B,EAAQ,2BAA2B,EAAQ,cAEhC,IAAA,CACX,GACA,MAEO,EAAS,OAAA,CAAQ,MAAY;AAClC,QAAM,IAAS,EAAgB,CAAO;AACtC,SAAO,EAAoB,EAAU,CAAM,CAAC;AAC9C,CAAC,GAGU,IAAA,CACX,GACA,MACe;AACf,QAAM,IAAS,MAAiB,EAAa,SAAS,IAAc,GAE9D,IAAW,EAAK,CAAA;AACtB,SAAI,CAAC,KAAY,OAAO,KAAK,CAAQ,EAAE,WAAW,IACzC,EAAO,IAAA,CAAK,MAAU,EAAM,IAAA,MAAU,IAAI,CAAC,IAE7C,EAAO,IAAA,CAAK,MAAU,EAAM,IAAA,CAAK,MAAQ,EAAc,EAAS,CAAA,KAAQ,CAAC,CAAC,CAAC;AACpF,GAEa,IAAA,CAAa,MACxB,OAAO,OAAO,CAAG,EAAE,OAAA,CAAQ,GAAK,MAAQ,IAAM,GAAK,CAAC"}
|
|
@@ -11,3 +11,4 @@ export declare const groupRecurrencesByDate: (recurrences: Recurrence[]) => Grou
|
|
|
11
11
|
export declare const getFrequencyLabel: (copy: RecurringCopy, repeatingTransaction: RepeatingTransaction, showOrdinal: boolean) => string;
|
|
12
12
|
export declare const getNextPaymentDate: (frequency: Frequency, date: Date, recurrenceDay?: number, secondRecurrenceDay?: number) => Date;
|
|
13
13
|
export declare const getNextUpcomingDate: (recurringTransaction: RepeatingTransaction, recurrences: Recurrence[]) => Date;
|
|
14
|
+
export declare const isEligibleRepeatingTransaction: (transaction: Transaction) => boolean;
|