@powerhousedao/design-system 6.0.0-dev.235 → 6.0.0-dev.237

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/dist/{button-C8doazjv.d.ts → button-DIE3LLBZ.d.ts} +1 -1
  2. package/dist/{button-C8doazjv.d.ts.map → button-DIE3LLBZ.d.ts.map} +1 -1
  3. package/dist/{character-counter-BWoglM2P.d.ts → character-counter-BZ-4xC7Q.d.ts} +1 -1
  4. package/dist/{character-counter-BWoglM2P.d.ts.map → character-counter-BZ-4xC7Q.d.ts.map} +1 -1
  5. package/dist/{checkbox-D9rmZ1dJ.d.ts → checkbox-BgS8z46p.d.ts} +3 -3
  6. package/dist/{checkbox-D9rmZ1dJ.d.ts.map → checkbox-BgS8z46p.d.ts.map} +1 -1
  7. package/dist/{checkbox-base-CZo-4eL0.d.ts → checkbox-base-Bh08IVG2.d.ts} +1 -1
  8. package/dist/{checkbox-base-CZo-4eL0.d.ts.map → checkbox-base-Bh08IVG2.d.ts.map} +1 -1
  9. package/dist/{command-DrrnJuvu.d.ts → command-COqe4AfR.d.ts} +9 -9
  10. package/dist/command-COqe4AfR.d.ts.map +1 -0
  11. package/dist/connect/index.d.ts +1266 -3
  12. package/dist/connect/index.d.ts.map +1 -0
  13. package/dist/connect/index.js +8193 -2
  14. package/dist/connect/index.js.map +1 -0
  15. package/dist/{content-DJVuhrPq.d.ts → content-ZWaCzypo.d.ts} +2 -2
  16. package/dist/{content-DJVuhrPq.d.ts.map → content-ZWaCzypo.d.ts.map} +1 -1
  17. package/dist/{enum-field-C-HqOUUb.d.ts → enum-field-7NPFL29j.d.ts} +4 -4
  18. package/dist/{enum-field-C-HqOUUb.d.ts.map → enum-field-7NPFL29j.d.ts.map} +1 -1
  19. package/dist/{form-CKRKn0TQ.d.ts → form-6Lmx7pU_.d.ts} +1 -1
  20. package/dist/{form-CKRKn0TQ.d.ts.map → form-6Lmx7pU_.d.ts.map} +1 -1
  21. package/dist/{form-description-CYkcMEzm.d.ts → form-description-Bsurk7mm.d.ts} +1 -1
  22. package/dist/{form-description-CYkcMEzm.d.ts.map → form-description-Bsurk7mm.d.ts.map} +1 -1
  23. package/dist/{form-group-C8kL6pdZ.d.ts → form-group-B092xF-f.d.ts} +1 -1
  24. package/dist/form-group-B092xF-f.d.ts.map +1 -0
  25. package/dist/{form-label-b6nQi0XO.d.ts → form-label-CURXUfpb.d.ts} +1 -1
  26. package/dist/{form-label-b6nQi0XO.d.ts.map → form-label-CURXUfpb.d.ts.map} +1 -1
  27. package/dist/{form-message-Dq72nBXz.d.ts → form-message-BeAVBzjc.d.ts} +1 -1
  28. package/dist/{form-message-Dq72nBXz.d.ts.map → form-message-BeAVBzjc.d.ts.map} +1 -1
  29. package/dist/{form-server-error-message-DXbaiTfF.d.ts → form-server-error-message-CbKMtocn.d.ts} +1 -1
  30. package/dist/{form-server-error-message-DXbaiTfF.d.ts.map → form-server-error-message-CbKMtocn.d.ts.map} +1 -1
  31. package/dist/{id-autocomplete-D_0Y3vO6.d.ts → id-autocomplete-DGTfhFRw.d.ts} +2 -2
  32. package/dist/{id-autocomplete-D_0Y3vO6.d.ts.map → id-autocomplete-DGTfhFRw.d.ts.map} +1 -1
  33. package/dist/{id-autocomplete-input-container-BBPnEQKE.d.ts → id-autocomplete-input-container-DefHskQg.d.ts} +2 -2
  34. package/dist/{id-autocomplete-input-container-BBPnEQKE.d.ts.map → id-autocomplete-input-container-DefHskQg.d.ts.map} +1 -1
  35. package/dist/{id-autocomplete-list-yagWAecF.d.ts → id-autocomplete-list-C5uiH5nJ.d.ts} +2 -2
  36. package/dist/{id-autocomplete-list-yagWAecF.d.ts.map → id-autocomplete-list-C5uiH5nJ.d.ts.map} +1 -1
  37. package/dist/{id-autocomplete-list-option-BtGmT-PL.d.ts → id-autocomplete-list-option-CyF3v8IB.d.ts} +2 -2
  38. package/dist/{id-autocomplete-list-option-BtGmT-PL.d.ts.map → id-autocomplete-list-option-CyF3v8IB.d.ts.map} +1 -1
  39. package/dist/{index-C8XGTcEE.d.ts → index-DoFR9kRM.d.ts} +4 -67
  40. package/dist/index-DoFR9kRM.d.ts.map +1 -0
  41. package/dist/index.d.ts +3 -3
  42. package/dist/{input-BpEQjaWV.d.ts → input-BMf1G8BP.d.ts} +1 -1
  43. package/dist/{input-BpEQjaWV.d.ts.map → input-BMf1G8BP.d.ts.map} +1 -1
  44. package/dist/{json-viewer-DaTgmzkS.d.ts → json-viewer-DD7b-PP2.d.ts} +1 -1
  45. package/dist/{json-viewer-DaTgmzkS.d.ts.map → json-viewer-DD7b-PP2.d.ts.map} +1 -1
  46. package/dist/{message-list-C4mPpBBa.d.ts → message-list-DDi6OrSM.d.ts} +2 -2
  47. package/dist/{message-list-C4mPpBBa.d.ts.map → message-list-DDi6OrSM.d.ts.map} +1 -1
  48. package/dist/{popover-XSBOuSih.d.ts → popover-BXlVJZZW.d.ts} +1 -1
  49. package/dist/{popover-XSBOuSih.d.ts.map → popover-BXlVJZZW.d.ts.map} +1 -1
  50. package/dist/{radio-eL0Oy86J.d.ts → radio-YzIhzpRk.d.ts} +1 -1
  51. package/dist/{radio-eL0Oy86J.d.ts.map → radio-YzIhzpRk.d.ts.map} +1 -1
  52. package/dist/{radio-group-Bkli6nUz.d.ts → radio-group-D2NSfihe.d.ts} +1 -1
  53. package/dist/{radio-group-Bkli6nUz.d.ts.map → radio-group-D2NSfihe.d.ts.map} +1 -1
  54. package/dist/{radio-group-field-CvEiKxgz.d.ts → radio-group-field-xAiLWNsq.d.ts} +3 -3
  55. package/dist/{radio-group-field-CvEiKxgz.d.ts.map → radio-group-field-xAiLWNsq.d.ts.map} +1 -1
  56. package/dist/{search-autocomplete-BJJkrZ1i.d.ts → search-autocomplete-CfSjqceY.d.ts} +2 -2
  57. package/dist/{search-autocomplete-BJJkrZ1i.d.ts.map → search-autocomplete-CfSjqceY.d.ts.map} +1 -1
  58. package/dist/{select-field-DTnErvyf.d.ts → select-field-U8KSDxbg.d.ts} +2 -2
  59. package/dist/{select-field-DTnErvyf.d.ts.map → select-field-U8KSDxbg.d.ts.map} +1 -1
  60. package/dist/{selected-content-BFFMrHZW.d.ts → selected-content-iwV6vmSI.d.ts} +2 -2
  61. package/dist/{selected-content-BFFMrHZW.d.ts.map → selected-content-iwV6vmSI.d.ts.map} +1 -1
  62. package/dist/{splitted-input-diff-BuvB5vhe.d.ts → splitted-input-diff-DSME-KaQ.d.ts} +2 -2
  63. package/dist/{splitted-input-diff-BuvB5vhe.d.ts.map → splitted-input-diff-DSME-KaQ.d.ts.map} +1 -1
  64. package/dist/style.css +3 -133
  65. package/dist/{text-field-DQ89eiZL.d.ts → text-field-Cxpz1D2u.d.ts} +3 -3
  66. package/dist/{text-field-DQ89eiZL.d.ts.map → text-field-Cxpz1D2u.d.ts.map} +1 -1
  67. package/dist/{text-input-diff-K3kzOkxj.d.ts → text-input-diff-bO84di00.d.ts} +2 -2
  68. package/dist/{text-input-diff-K3kzOkxj.d.ts.map → text-input-diff-bO84di00.d.ts.map} +1 -1
  69. package/dist/{text-input-C_Dl2L8-.d.ts → text-input-t0uGOMAO.d.ts} +3 -3
  70. package/dist/{text-input-C_Dl2L8-.d.ts.map → text-input-t0uGOMAO.d.ts.map} +1 -1
  71. package/dist/{tooltip-CsucyiCV.d.ts → tooltip-Db1dLIxg.d.ts} +1 -1
  72. package/dist/{tooltip-CsucyiCV.d.ts.map → tooltip-Db1dLIxg.d.ts.map} +1 -1
  73. package/dist/{types-C04Q_Fan.d.ts → types-BDeBOEOj.d.ts} +1 -1
  74. package/dist/{types-C04Q_Fan.d.ts.map → types-BDeBOEOj.d.ts.map} +1 -1
  75. package/dist/{types-BTq-St7H.d.ts → types-BLss8ZBX.d.ts} +1 -1
  76. package/dist/{types-BTq-St7H.d.ts.map → types-BLss8ZBX.d.ts.map} +1 -1
  77. package/dist/{types-Bsn62tJB.d.ts → types-BzoMu6VB.d.ts} +1 -1
  78. package/dist/{types-Bsn62tJB.d.ts.map → types-BzoMu6VB.d.ts.map} +1 -1
  79. package/dist/ui/components/button/button.d.ts +1 -1
  80. package/dist/ui/components/character-counter/character-counter.d.ts +1 -1
  81. package/dist/ui/components/checkbox/checkbox-base.d.ts +1 -1
  82. package/dist/ui/components/checkbox/checkbox.d.ts +1 -1
  83. package/dist/ui/components/command/command.d.ts +1 -1
  84. package/dist/ui/components/enum-field/enum-field.d.ts +1 -1
  85. package/dist/ui/components/enum-field/types.d.ts +1 -1
  86. package/dist/ui/components/form/form.d.ts +1 -1
  87. package/dist/ui/components/form-description/form-description.d.ts +1 -1
  88. package/dist/ui/components/form-group/form-group.d.ts +1 -1
  89. package/dist/ui/components/form-label/form-label.d.ts +1 -1
  90. package/dist/ui/components/form-message/form-message.d.ts +1 -1
  91. package/dist/ui/components/form-message/form-server-error-message.d.ts +1 -1
  92. package/dist/ui/components/form-message/message-list.d.ts +1 -1
  93. package/dist/ui/components/id-autocomplete/id-autocomplete-input-container.d.ts +1 -1
  94. package/dist/ui/components/id-autocomplete/id-autocomplete-list-option.d.ts +1 -1
  95. package/dist/ui/components/id-autocomplete/id-autocomplete-list.d.ts +1 -1
  96. package/dist/ui/components/id-autocomplete/id-autocomplete.d.ts +1 -1
  97. package/dist/ui/components/id-autocomplete/types.d.ts +1 -1
  98. package/dist/ui/components/id-autocomplete/use-id-autocomplete.d.ts +1 -1
  99. package/dist/ui/components/index.d.ts +36 -36
  100. package/dist/ui/components/input/input.d.ts +1 -1
  101. package/dist/ui/components/input/splitted-input-diff.d.ts +1 -1
  102. package/dist/ui/components/input/subcomponent/text-diff.d.ts +1 -1
  103. package/dist/ui/components/json-viewer/json-viewer.d.ts +1 -1
  104. package/dist/ui/components/popover/popover.d.ts +1 -1
  105. package/dist/ui/components/radio-group-field/radio-group-field.d.ts +1 -1
  106. package/dist/ui/components/radio-group-field/radio-group.d.ts +1 -1
  107. package/dist/ui/components/radio-group-field/radio.d.ts +1 -1
  108. package/dist/ui/components/search-autocomplete/index.d.ts +3 -3
  109. package/dist/ui/components/search-autocomplete/search-autocomplete.d.ts +1 -1
  110. package/dist/ui/components/search-autocomplete/types.d.ts +1 -1
  111. package/dist/ui/components/search-autocomplete/use-search-autocomplete.d.ts +1 -1
  112. package/dist/ui/components/select-field/content.d.ts +1 -1
  113. package/dist/ui/components/select-field/select-field.d.ts +1 -1
  114. package/dist/ui/components/select-field/selected-content.d.ts +1 -1
  115. package/dist/ui/components/select-field/subcomponents/CommandItemList.d.ts +1 -1
  116. package/dist/ui/components/select-field/use-select-field.d.ts +1 -1
  117. package/dist/ui/components/text-field/text-field.d.ts +1 -1
  118. package/dist/ui/components/text-input/text-input-diff.d.ts +1 -1
  119. package/dist/ui/components/text-input/text-input.d.ts +1 -1
  120. package/dist/ui/components/text-input/types.d.ts +1 -1
  121. package/dist/ui/components/tooltip/tooltip.d.ts +1 -1
  122. package/dist/ui/components/types.d.ts +1 -1
  123. package/dist/ui/components/value-transformer/value-transformer.d.ts +1 -1
  124. package/dist/ui/components/with-field-validation/with-field-validation.d.ts +1 -1
  125. package/dist/ui/index.d.ts +38 -38
  126. package/dist/ui/lib/date-picker.d.ts +1 -1
  127. package/dist/ui/lib/shared-value-transformers.d.ts +1 -1
  128. package/dist/ui/lib/types.d.ts +1 -1
  129. package/dist/ui/types.d.ts +2 -2
  130. package/dist/{use-id-autocomplete-DrTVtqMy.d.ts → use-id-autocomplete-BRzpIF4U.d.ts} +2 -2
  131. package/dist/{use-id-autocomplete-DrTVtqMy.d.ts.map → use-id-autocomplete-BRzpIF4U.d.ts.map} +1 -1
  132. package/dist/{use-search-autocomplete-IfcQ_gKh.d.ts → use-search-autocomplete-ZLxfAC6X.d.ts} +2 -2
  133. package/dist/{use-search-autocomplete-IfcQ_gKh.d.ts.map → use-search-autocomplete-ZLxfAC6X.d.ts.map} +1 -1
  134. package/dist/{value-transformer-2yvrA5Rp.d.ts → value-transformer-MGhQTCdM.d.ts} +2 -2
  135. package/dist/{value-transformer-2yvrA5Rp.d.ts.map → value-transformer-MGhQTCdM.d.ts.map} +1 -1
  136. package/dist/{with-field-validation-Bd0Nq4k-.d.ts → with-field-validation-DWMigXJz.d.ts} +2 -2
  137. package/dist/{with-field-validation-Bd0Nq4k-.d.ts.map → with-field-validation-DWMigXJz.d.ts.map} +1 -1
  138. package/package.json +4 -13
  139. package/dist/command-DrrnJuvu.d.ts.map +0 -1
  140. package/dist/connect-BSkeWkEI.js +0 -8340
  141. package/dist/connect-BSkeWkEI.js.map +0 -1
  142. package/dist/form-group-C8kL6pdZ.d.ts.map +0 -1
  143. package/dist/index-C8XGTcEE.d.ts.map +0 -1
  144. package/dist/index-VqN1Wx2S.d.ts +0 -1201
  145. package/dist/index-VqN1Wx2S.d.ts.map +0 -1
  146. package/dist/rwa/index.d.ts +0 -791
  147. package/dist/rwa/index.d.ts.map +0 -1
  148. package/dist/rwa/index.js +0 -2686
  149. package/dist/rwa/index.js.map +0 -1
  150. /package/dist/{index--okzibnx.d.ts → index-BN8Gwmlj.d.ts} +0 -0
  151. /package/dist/{index-E7Wvm5uX.d.ts → index-Dw5cCt-A.d.ts} +0 -0
  152. /package/dist/{index-J3R2mDFQ.d.ts → index-qM4PwHTs.d.ts} +0 -0
package/dist/rwa/index.js DELETED
@@ -1,2686 +0,0 @@
1
- import { i as ConnectTooltipProvider, r as ConnectTooltip } from "../document-timeline-BTTeXWMa.js";
2
- import { d as Pagination, f as mergeClassNameProps, h as Icon, m as Modal, r as usePagination, w as PowerhouseButton } from "../src-DTHkTkyy.js";
3
- import { Dt as EditorActionButtons, Jt as Combobox } from "../connect-BSkeWkEI.js";
4
- import { Fragment, createContext, forwardRef, memo, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react";
5
- import { twJoin, twMerge } from "tailwind-merge";
6
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
- import { Controller, useFieldArray, useForm, useWatch } from "react-hook-form";
8
- import { Content, List, Root, Trigger } from "@radix-ui/react-tabs";
9
- import { NumericFormat } from "react-number-format";
10
- import { all, create } from "mathjs";
11
- import { formatInTimeZone } from "date-fns-tz/formatInTimeZone";
12
- import { orderBy } from "natural-orderby";
13
- const tableNames = {
14
- SERVICE_PROVIDER_FEE_TYPE: "SERVICE_PROVIDER_FEE_TYPE",
15
- FIXED_INCOME_TYPE: "FIXED_INCOME_TYPE",
16
- ACCOUNT: "ACCOUNT",
17
- TRANSACTION: "TRANSACTION",
18
- ASSET: "ASSET",
19
- SPV: "SPV"
20
- };
21
- const tableLabels = {
22
- SERVICE_PROVIDER_FEE_TYPE: "Service Provider Fee Type",
23
- FIXED_INCOME_TYPE: "Fixed Income Asset Type",
24
- ACCOUNT: "Account",
25
- TRANSACTION: "Transaction",
26
- ASSET: "Asset",
27
- SPV: "SPV"
28
- };
29
- const editorStateKeysByTableName = {
30
- SERVICE_PROVIDER_FEE_TYPE: "serviceProviderFeeTypes",
31
- FIXED_INCOME_TYPE: "fixedIncomeTypes",
32
- ACCOUNT: "accounts",
33
- TRANSACTION: "transactions",
34
- ASSET: "portfolio",
35
- SPV: "spvs"
36
- };
37
- const deleteEditorActionInputsByTableName = {
38
- SERVICE_PROVIDER_FEE_TYPE: "DELETE_SERVICE_PROVIDER_FEE_TYPE",
39
- FIXED_INCOME_TYPE: "DELETE_FIXED_INCOME_TYPE",
40
- ACCOUNT: "DELETE_ACCOUNT",
41
- TRANSACTION: "DELETE_TRANSACTION",
42
- ASSET: "DELETE_ASSET",
43
- SPV: "DELETE_SPV"
44
- };
45
- //#endregion
46
- //#region src/rwa/constants/table.ts
47
- const defaultColumnCountByTableWidth = {
48
- 1520: 10,
49
- 1394: 9,
50
- 1239: 8,
51
- 1112: 7,
52
- 984: 6
53
- };
54
- const cashTransactionSignByTransactionType = {
55
- AssetSale: 1,
56
- PrincipalDraw: 1,
57
- AssetPurchase: -1,
58
- PrincipalReturn: -1,
59
- FeesIncome: 1,
60
- FeesPayment: -1,
61
- InterestIncome: 1,
62
- InterestPayment: -1
63
- };
64
- const assetTransactionSignByTransactionType = {
65
- AssetSale: -1,
66
- AssetPurchase: 1
67
- };
68
- function getStateKeyForTableName(tableName) {
69
- return {
70
- ASSET: "portfolio",
71
- TRANSACTION: "transactions",
72
- ACCOUNT: "accounts",
73
- FIXED_INCOME_TYPE: "fixedIncomeTypes",
74
- SERVICE_PROVIDER_FEE_TYPE: "serviceProviderFeeTypes",
75
- SPV: "spvs"
76
- }[tableName];
77
- }
78
- function getTableNameFor(action) {
79
- return action.type.split("_").slice(1).join("_");
80
- }
81
- function getActionOperationType(action) {
82
- return action.type.split("_")[0];
83
- }
84
- //#endregion
85
- //#region src/rwa/components/formatted-number.tsx
86
- function FormattedNumber(props) {
87
- const { value, currency, decimalScale = 2, thousandSeparator = ",", fixedDecimalScale = true } = props;
88
- return /* @__PURE__ */ jsx(NumericFormat, {
89
- decimalScale,
90
- displayType: "text",
91
- fixedDecimalScale,
92
- prefix: currency === "USD" ? "$" : void 0,
93
- thousandSeparator,
94
- value
95
- });
96
- }
97
- //#endregion
98
- //#region src/rwa/constants/transactions.ts
99
- const ASSET_PURCHASE = "AssetPurchase";
100
- const ASSET_SALE = "AssetSale";
101
- const PRINCIPAL_DRAW = "PrincipalDraw";
102
- const PRINCIPAL_RETURN = "PrincipalReturn";
103
- const INTEREST_INCOME = "InterestIncome";
104
- const INTEREST_PAYMENT = "InterestPayment";
105
- const FEES_INCOME = "FeesIncome";
106
- const FEES_PAYMENT = "FeesPayment";
107
- const principalGroupTransactions = [PRINCIPAL_DRAW, PRINCIPAL_RETURN];
108
- const assetGroupTransactions = [ASSET_PURCHASE, ASSET_SALE];
109
- const feesTransactions = [FEES_INCOME, FEES_PAYMENT];
110
- const interestTransactions = [INTEREST_INCOME, INTEREST_PAYMENT];
111
- const allGroupTransactionTypes = [
112
- ...principalGroupTransactions,
113
- ...assetGroupTransactions,
114
- ...feesTransactions,
115
- ...interestTransactions
116
- ];
117
- const groupTransactionTypeLabels = {
118
- AssetPurchase: "Asset purchase",
119
- AssetSale: "Asset sale",
120
- PrincipalDraw: "Principal draw",
121
- PrincipalReturn: "Principal return",
122
- InterestIncome: "Interest income",
123
- InterestPayment: "Interest payment",
124
- FeesIncome: "Fees income",
125
- FeesPayment: "Fees payment"
126
- };
127
- //#endregion
128
- //#region src/rwa/utils/calculations.ts
129
- function sumTotalForProperty(items, property) {
130
- return items.reduce((acc, item) => acc + Number(item[property]), 0);
131
- }
132
- const math = create(all, { number: "BigNumber" });
133
- function calculateCurrentValue(props) {
134
- const { asset, transactions, fixedIncomeTypes, currentDate = /* @__PURE__ */ new Date() } = props;
135
- if (!asset?.maturity) return null;
136
- const fixedIncomeType = fixedIncomeTypes.find(({ id }) => id === asset.fixedIncomeTypeId);
137
- if (!fixedIncomeType) return null;
138
- if (fixedIncomeType.name !== "Treasury Bill") return null;
139
- const purchaseTransactionsForAsset = transactions.filter(({ type, fixedIncomeTransaction }) => type === "AssetPurchase" && fixedIncomeTransaction?.assetId === asset.id);
140
- const saleTransactionsForAsset = transactions.filter(({ type, fixedIncomeTransaction }) => type === "AssetSale" && fixedIncomeTransaction?.assetId === asset.id);
141
- if (!purchaseTransactionsForAsset.length && !saleTransactionsForAsset.length) return null;
142
- const currentDateMs = math.bignumber(currentDate.getTime());
143
- const maturityDateMs = math.bignumber(new Date(asset.maturity).getTime());
144
- if (maturityDateMs.lessThan(currentDateMs)) return null;
145
- const purchaseDateMs = math.bignumber(new Date(asset.purchaseDate).getTime());
146
- const sumQuantities = calculateSumQuantity(purchaseTransactionsForAsset).sub(calculateSumQuantity(saleTransactionsForAsset));
147
- const salesProceeds = math.bignumber(asset.salesProceeds);
148
- const realizedSurplus = math.bignumber(asset.realizedSurplus);
149
- const currentPurchaseProceeds = math.bignumber(asset.purchaseProceeds).sub(salesProceeds).add(realizedSurplus);
150
- const totalDiscount = sumQuantities.sub(currentPurchaseProceeds);
151
- return currentDateMs.sub(purchaseDateMs).div(maturityDateMs.sub(purchaseDateMs)).mul(totalDiscount).add(currentPurchaseProceeds).toNumber();
152
- }
153
- function calculateSumQuantity(transactions) {
154
- return transactions.reduce((sum, { fixedIncomeTransaction }) => {
155
- if (!fixedIncomeTransaction) return sum;
156
- return sum.add(math.bignumber(fixedIncomeTransaction.amount));
157
- }, math.bignumber(0));
158
- }
159
- //#endregion
160
- //#region src/rwa/utils/date.ts
161
- function formatDateForDisplay(date, displayTime = true, isUTC = false) {
162
- const formatString = displayTime ? "yyyy/MM/dd, HH:mm:ss zzz" : "yyyy/MM/dd";
163
- return formatInTimeZone(date, isUTC ? "UTC" : getTimeZone(), formatString);
164
- }
165
- function isISODate(str) {
166
- if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(str)) return false;
167
- const d = new Date(str);
168
- return d instanceof Date && !isNaN(d.getTime()) && d.toISOString() === str;
169
- }
170
- function getTimeZone() {
171
- return Intl.DateTimeFormat().resolvedOptions().timeZone;
172
- }
173
- function isoDateStringToDateInput(isoDateString, withTime = false) {
174
- const format = withTime ? "yyyy-MM-dd'T'HH:mm:ss" : "yyyy-MM-dd";
175
- return formatInTimeZone(isoDateString, getTimeZone(), format);
176
- }
177
- //#endregion
178
- //#region src/rwa/utils/validators.ts
179
- function isAssetGroupTransactionType(type) {
180
- return assetGroupTransactions.includes(type);
181
- }
182
- function isFixedIncomeAsset(asset) {
183
- if (!asset) return false;
184
- if (asset.type === "FixedIncome") return true;
185
- if ("fixedIncomeId" in asset) return true;
186
- return false;
187
- }
188
- function isCashAsset(asset) {
189
- if (!asset) return false;
190
- if (asset.type === "Cash") return true;
191
- if ("currency" in asset) return true;
192
- return false;
193
- }
194
- function getFixedIncomeAssets(portfolio) {
195
- return portfolio.filter((a) => isFixedIncomeAsset(a));
196
- }
197
- function getCashAsset(portfolio) {
198
- const cashAsset = portfolio.find((a) => isCashAsset(a));
199
- if (!cashAsset) throw new Error("Cash asset not found");
200
- return cashAsset;
201
- }
202
- //#endregion
203
- //#region src/rwa/utils/table.tsx
204
- function handleDateInTable(maybeDate, displayTime = true) {
205
- if (maybeDate instanceof Date || isISODate(maybeDate)) return formatDateForDisplay(maybeDate instanceof Date ? maybeDate.toISOString() : maybeDate, displayTime);
206
- return maybeDate;
207
- }
208
- function handleTableDatum(datum, decimalScale = 2, displayTime = true) {
209
- if (datum === null || datum === void 0) return "--";
210
- if (typeof datum === "number") return /* @__PURE__ */ jsx(FormattedNumber, {
211
- decimalScale,
212
- value: datum
213
- });
214
- return handleDateInTable(datum, displayTime);
215
- }
216
- function calculateUnitPrice(cashAmount, fixedIncomeAmount) {
217
- if (!cashAmount || !fixedIncomeAmount) return 0;
218
- return cashAmount / fixedIncomeAmount;
219
- }
220
- function calculateCashBalanceChange(transactionType, cashAmount, fees) {
221
- if (!cashAmount || !transactionType) return 0;
222
- const sign = cashTransactionSignByTransactionType[transactionType];
223
- const totalFees = (fees?.map((fee) => fee.amount).filter(Boolean) ?? []).reduce((acc, fee) => acc + fee, 0);
224
- return cashAmount * sign - totalFees;
225
- }
226
- function makeFixedIncomeTypesTableData(state) {
227
- const { fixedIncomeTypes } = state;
228
- return addItemNumber(fixedIncomeTypes);
229
- }
230
- function makeSPVsTableData(state) {
231
- const { spvs } = state;
232
- return addItemNumber(spvs);
233
- }
234
- function makeAssetsTableData(state) {
235
- const { portfolio, transactions, fixedIncomeTypes } = state;
236
- const currentDate = /* @__PURE__ */ new Date();
237
- return addItemNumber(getFixedIncomeAssets(portfolio).map((fixedIncome) => {
238
- const currentValue = calculateCurrentValue({
239
- asset: fixedIncome,
240
- currentDate,
241
- transactions,
242
- fixedIncomeTypes
243
- });
244
- return {
245
- ...fixedIncome,
246
- currentValue
247
- };
248
- }));
249
- }
250
- function maybeAddSignToAmount(amount, sign) {
251
- if (!amount) return amount;
252
- return amount * sign;
253
- }
254
- function makeGroupTransactionsTableData(state) {
255
- const { transactions, portfolio } = state;
256
- const fixedIncomes = getFixedIncomeAssets(portfolio);
257
- return addItemNumber(transactions.map((transaction) => {
258
- const id = transaction.id;
259
- const entryTime = transaction.entryTime;
260
- const asset = fixedIncomes.find((asset) => asset.id === transaction.fixedIncomeTransaction?.assetId)?.name;
261
- const type = transaction.type;
262
- const typeLabel = groupTransactionTypeLabels[type];
263
- const cashTransactionSign = cashTransactionSignByTransactionType[type];
264
- const assetTransactionSign = isAssetGroupTransactionType(type) ? assetTransactionSignByTransactionType[type] : 1;
265
- const quantity = maybeAddSignToAmount(transaction.fixedIncomeTransaction?.amount, assetTransactionSign);
266
- const cashAmount = maybeAddSignToAmount(transaction.cashTransaction.amount, cashTransactionSign);
267
- const totalFees = feesTransactions.includes(transaction.type) ? maybeAddSignToAmount(transaction.cashTransaction.amount, transaction.type === "FeesIncome" ? -1 : 1) ?? 0 : transaction.fees?.reduce((acc, fee) => acc + fee.amount, 0) ?? 0;
268
- const cashBalanceChange = transaction.cashBalanceChange;
269
- return {
270
- ...transaction,
271
- id,
272
- type,
273
- typeLabel,
274
- entryTime,
275
- asset,
276
- quantity,
277
- cashAmount,
278
- totalFees,
279
- cashBalanceChange
280
- };
281
- }));
282
- }
283
- function makeAccountsTableData(state) {
284
- const { accounts, principalLenderAccountId } = state;
285
- return addItemNumber(accounts.filter((account) => account.id !== principalLenderAccountId));
286
- }
287
- function makeServiceProviderFeeTypesTableData(state) {
288
- const { serviceProviderFeeTypes, accounts } = state;
289
- return addItemNumber(serviceProviderFeeTypes.map((serviceProviderFeeType) => {
290
- const account = accounts.find((account) => account.id === serviceProviderFeeType.accountId);
291
- return {
292
- ...serviceProviderFeeType,
293
- accountName: account?.label,
294
- accountReference: account?.reference
295
- };
296
- }));
297
- }
298
- function addItemNumber(items) {
299
- return items.map((item, index) => ({
300
- ...item,
301
- itemNumber: index + 1
302
- }));
303
- }
304
- function makeTableData(tableName, state) {
305
- return tableDataMakersByTableName[tableName](state);
306
- }
307
- const tableDataMakersByTableName = {
308
- ASSET: makeAssetsTableData,
309
- TRANSACTION: makeGroupTransactionsTableData,
310
- ACCOUNT: makeAccountsTableData,
311
- FIXED_INCOME_TYPE: makeFixedIncomeTypesTableData,
312
- SERVICE_PROVIDER_FEE_TYPE: makeServiceProviderFeeTypesTableData,
313
- SPV: makeSPVsTableData
314
- };
315
- //#endregion
316
- //#region src/rwa/context/editor-context.tsx
317
- const EditorContext = /* @__PURE__ */ createContext({
318
- accounts: [],
319
- fixedIncomeTypes: [],
320
- portfolio: [],
321
- principalLenderAccountId: "",
322
- serviceProviderFeeTypes: [],
323
- spvs: [],
324
- transactions: [],
325
- fixedIncomes: [],
326
- cashAsset: {
327
- id: "",
328
- type: "Cash",
329
- currency: "USD",
330
- balance: 0,
331
- spvId: ""
332
- },
333
- isAllowedToCreateDocuments: false,
334
- isAllowedToEditDocuments: false,
335
- canUndo: false,
336
- canRedo: false,
337
- operation: null,
338
- onSwitchboardLinkClick: void 0,
339
- selectedTableItem: null,
340
- selectedTableName: null,
341
- getIsFormOpen: () => false,
342
- clearSelected: () => {},
343
- viewItem: () => {},
344
- createItem: () => {},
345
- editItem: () => {},
346
- onExport: () => {},
347
- onClose: () => {},
348
- handleUndo: () => {},
349
- handleRedo: () => {},
350
- onShowRevisionHistory: () => {},
351
- handleAction: () => {}
352
- });
353
- EditorContext.displayName = "EditorContext";
354
- function tableReducer(state, action) {
355
- switch (action.type) {
356
- case "VIEW_ITEM": return {
357
- selectedTableItem: action.item,
358
- selectedTableName: action.tableName,
359
- operation: "view"
360
- };
361
- case "CREATE_ITEM": return {
362
- selectedTableItem: null,
363
- selectedTableName: action.tableName,
364
- operation: "create"
365
- };
366
- case "EDIT_ITEM": return {
367
- selectedTableItem: action.item,
368
- selectedTableName: action.tableName,
369
- operation: "edit"
370
- };
371
- case "CLEAR_SELECTED": return {
372
- selectedTableItem: null,
373
- selectedTableName: null,
374
- operation: null
375
- };
376
- default: return state;
377
- }
378
- }
379
- function RWAEditorContextProvider(props) {
380
- const { children, state, isAllowedToCreateDocuments, isAllowedToEditDocuments, canUndo, canRedo, undo, redo, editorDispatcher, onExport, onClose, onSwitchboardLinkClick, onShowRevisionHistory } = props;
381
- const [editorState, setEditorState] = useState(state);
382
- const stateRef = useRef(state);
383
- const [tableState, tableDispatch] = useReducer(tableReducer, {
384
- selectedTableItem: null,
385
- selectedTableName: null,
386
- operation: null
387
- });
388
- const { selectedTableItem, selectedTableName, operation } = tableState;
389
- useEffect(() => {
390
- if (operation === null || operation === "view") setEditorState(stateRef.current);
391
- }, [operation, state]);
392
- useEffect(() => {
393
- stateRef.current = state;
394
- }, [state]);
395
- const { accounts, fixedIncomeTypes, portfolio, principalLenderAccountId, serviceProviderFeeTypes, spvs, transactions } = editorState;
396
- const cashAsset = useMemo(() => getCashAsset(portfolio), [portfolio]);
397
- const fixedIncomes = useMemo(() => getFixedIncomeAssets(portfolio), [portfolio]);
398
- const handleUndo = useCallback(() => {
399
- if (!canUndo) return;
400
- undo();
401
- }, [canUndo, undo]);
402
- const handleRedo = useCallback(() => {
403
- if (!canRedo) return;
404
- redo();
405
- }, [canRedo, redo]);
406
- const getIsFormOpen = useCallback((tableName) => selectedTableName === tableName, [selectedTableName]);
407
- const viewItem = useCallback((item, tableName) => {
408
- tableDispatch({
409
- type: "VIEW_ITEM",
410
- item,
411
- tableName
412
- });
413
- }, []);
414
- const createItem = useCallback((tableName) => {
415
- tableDispatch({
416
- type: "CREATE_ITEM",
417
- tableName
418
- });
419
- }, []);
420
- const editItem = useCallback((item, tableName) => {
421
- tableDispatch({
422
- type: "EDIT_ITEM",
423
- item,
424
- tableName
425
- });
426
- }, []);
427
- const clearSelected = useCallback(() => {
428
- tableDispatch({ type: "CLEAR_SELECTED" });
429
- setEditorState(stateRef.current);
430
- }, []);
431
- const handleAction = useCallback((action) => {
432
- try {
433
- const result = editorDispatcher(action);
434
- const actionOperationType = getActionOperationType(action);
435
- if (actionOperationType === "DELETE" || !result) {
436
- clearSelected();
437
- return;
438
- }
439
- const tableName = getTableNameFor(action);
440
- const stateKey = getStateKeyForTableName(tableName);
441
- const currentStateForKey = stateRef.current[stateKey];
442
- if (typeof currentStateForKey === "string") return;
443
- if (actionOperationType === "CREATE") {
444
- const newStateForKey = [...currentStateForKey, result];
445
- const newState = {
446
- ...stateRef.current,
447
- [stateKey]: newStateForKey
448
- };
449
- stateRef.current = newState;
450
- setEditorState(newState);
451
- if (tableName === selectedTableName) {
452
- const newTableItem = makeTableData(tableName, newState).find((item) => item.id === result.id);
453
- if (newTableItem) viewItem(newTableItem, tableName);
454
- }
455
- }
456
- if (actionOperationType === "EDIT") {
457
- const newStateForKey = currentStateForKey.map((item) => item.id === result.id ? result : item);
458
- const newState = {
459
- ...stateRef.current,
460
- [stateKey]: newStateForKey
461
- };
462
- stateRef.current = newState;
463
- setEditorState(newState);
464
- const newTableItem = makeTableData(tableName, newState).find((item) => item.id === result.id);
465
- if (newTableItem) editItem(newTableItem, tableName);
466
- }
467
- } catch (error) {
468
- console.error(`Failed to dispatch action ${action.type}`, error);
469
- }
470
- }, [
471
- clearSelected,
472
- editorDispatcher,
473
- editItem,
474
- selectedTableName,
475
- viewItem
476
- ]);
477
- const value = useMemo(() => ({
478
- accounts,
479
- fixedIncomeTypes,
480
- portfolio,
481
- principalLenderAccountId,
482
- serviceProviderFeeTypes,
483
- spvs,
484
- transactions,
485
- cashAsset,
486
- fixedIncomes,
487
- canUndo,
488
- canRedo,
489
- isAllowedToCreateDocuments,
490
- isAllowedToEditDocuments,
491
- selectedTableItem,
492
- selectedTableName,
493
- operation,
494
- handleAction,
495
- handleUndo,
496
- handleRedo,
497
- viewItem,
498
- createItem,
499
- editItem,
500
- clearSelected,
501
- getIsFormOpen,
502
- onExport,
503
- onClose,
504
- onSwitchboardLinkClick,
505
- onShowRevisionHistory
506
- }), [
507
- accounts,
508
- canRedo,
509
- canUndo,
510
- cashAsset,
511
- clearSelected,
512
- createItem,
513
- editItem,
514
- fixedIncomeTypes,
515
- fixedIncomes,
516
- getIsFormOpen,
517
- handleAction,
518
- handleRedo,
519
- handleUndo,
520
- isAllowedToCreateDocuments,
521
- isAllowedToEditDocuments,
522
- onClose,
523
- onExport,
524
- onShowRevisionHistory,
525
- onSwitchboardLinkClick,
526
- operation,
527
- portfolio,
528
- principalLenderAccountId,
529
- selectedTableItem,
530
- selectedTableName,
531
- serviceProviderFeeTypes,
532
- spvs,
533
- transactions,
534
- viewItem
535
- ]);
536
- return /* @__PURE__ */ jsx(EditorContext.Provider, {
537
- value,
538
- children
539
- });
540
- }
541
- function useEditorContext() {
542
- return useContext(EditorContext);
543
- }
544
- //#endregion
545
- //#region src/rwa/components/table-cell.tsx
546
- const RWATableCell = (props) => /* @__PURE__ */ jsx("td", {
547
- ...props,
548
- className: twMerge("truncate border-l border-gray-300 px-3 py-2 text-xs font-medium text-gray-900 first:border-l-0", props.className)
549
- });
550
- function ItemNumberCell(props) {
551
- return /* @__PURE__ */ jsx(RWATableCell, {
552
- className: "w-4",
553
- children: props.itemNumber
554
- });
555
- }
556
- function MoreDetailsCell(props) {
557
- const { isSelected, tableName, tableItem } = props;
558
- const { viewItem, clearSelected } = useEditorContext();
559
- return /* @__PURE__ */ jsx(RWATableCell, {
560
- className: "w-4",
561
- children: /* @__PURE__ */ jsx("button", {
562
- className: "flex size-full items-center justify-center",
563
- onClick: useCallback(() => {
564
- if (isSelected) {
565
- clearSelected();
566
- return;
567
- }
568
- viewItem(tableItem, tableName);
569
- }, [
570
- clearSelected,
571
- isSelected,
572
- tableItem,
573
- tableName,
574
- viewItem
575
- ]),
576
- children: /* @__PURE__ */ jsx(Icon, {
577
- className: twMerge("text-gray-600", isSelected && "rotate-180"),
578
- name: "CaretDown",
579
- size: 16
580
- })
581
- })
582
- });
583
- }
584
- //#endregion
585
- //#region src/rwa/components/table-row.tsx
586
- const RWATableRow = /* @__PURE__ */ forwardRef(function RWATableRow(props, ref) {
587
- const { children, className, ...delegated } = props;
588
- return /* @__PURE__ */ jsx("tr", {
589
- ...delegated,
590
- className: twMerge("odd:bg-white even:bg-gray-50", className),
591
- ref,
592
- children
593
- });
594
- });
595
- //#endregion
596
- //#region src/rwa/hooks/useSortTableItems.ts
597
- /**
598
- * Takes a list of items and returns a sorted list of items and a sort descriptor.
599
- * @param items - The list of items to sort.
600
- * @returns An object containing the sorted items and a sort handler func
601
- */
602
- function useSortTableItems(items) {
603
- const [sortedItems, setSortedItems] = useState(items);
604
- const [column, setColumn] = useState();
605
- const [direction, setDirection] = useState("asc");
606
- const sortHandler = useCallback((column, direction) => {
607
- setColumn(column);
608
- setDirection(direction);
609
- }, []);
610
- useEffect(() => {
611
- if (!items) return;
612
- if (!column) {
613
- setSortedItems(items);
614
- return;
615
- }
616
- setSortedItems(orderBy(items, [column], [direction]));
617
- }, [
618
- column,
619
- direction,
620
- items,
621
- sortHandler
622
- ]);
623
- return useMemo(() => ({
624
- sortedItems,
625
- sortHandler
626
- }), [sortedItems, sortHandler]);
627
- }
628
- //#endregion
629
- //#region src/rwa/hooks/useTableData.tsx
630
- function useTableData(tableName) {
631
- const inputs = useEditorContext();
632
- const { sortedItems, sortHandler } = useSortTableItems(useMemo(() => {
633
- return makeTableData(tableName, inputs);
634
- }, [inputs, tableName]));
635
- return useMemo(() => ({
636
- tableData: sortedItems ?? [],
637
- sortHandler
638
- }), [sortedItems, sortHandler]);
639
- }
640
- //#endregion
641
- //#region src/rwa/constants/dependent-items.ts
642
- function useDependentItemProps(tableName, itemId) {
643
- const { fixedIncomes, serviceProviderFeeTypes, transactions } = useEditorContext();
644
- return useMemo(() => {
645
- if (!itemId) return [];
646
- switch (tableName) {
647
- case "TRANSACTION": return [];
648
- case "SPV": return [{
649
- dependentTableName: "ASSET",
650
- dependentItems: makeDependentAssetsList(tableName, itemId, fixedIncomes)
651
- }];
652
- case "FIXED_INCOME_TYPE": return [{
653
- dependentTableName: "ASSET",
654
- dependentItems: makeDependentAssetsList(tableName, itemId, fixedIncomes)
655
- }];
656
- case "ASSET": return [{
657
- dependentTableName: "TRANSACTION",
658
- dependentItems: makeDependentTransactionsList(tableName, itemId, transactions)
659
- }];
660
- case "SERVICE_PROVIDER_FEE_TYPE": return [{
661
- dependentTableName: "TRANSACTION",
662
- dependentItems: makeDependentTransactionsList(tableName, itemId, transactions)
663
- }];
664
- case "ACCOUNT": return [{
665
- dependentTableName: "TRANSACTION",
666
- dependentItems: makeDependentTransactionsList(tableName, itemId, transactions)
667
- }, {
668
- dependentTableName: "SERVICE_PROVIDER_FEE_TYPE",
669
- dependentItems: makeDependentServiceProviderFeeTypesList(itemId, serviceProviderFeeTypes)
670
- }];
671
- }
672
- }, [
673
- fixedIncomes,
674
- itemId,
675
- serviceProviderFeeTypes,
676
- tableName,
677
- transactions
678
- ]);
679
- }
680
- function makeDependentServiceProviderFeeTypesList(itemId, serviceProviderFeeTypes) {
681
- const makeLabel = (asset) => ({
682
- id: asset.id,
683
- label: asset.name
684
- });
685
- return serviceProviderFeeTypes.filter((f) => f.accountId === itemId).map(makeLabel);
686
- }
687
- function makeDependentAssetsList(tableName, itemId, assets) {
688
- const makeLabel = (asset) => ({
689
- id: asset.id,
690
- label: asset.name
691
- });
692
- switch (tableName) {
693
- case "FIXED_INCOME_TYPE": return assets.filter((asset) => asset.fixedIncomeTypeId === itemId).map(makeLabel);
694
- case "SPV": return assets.filter((asset) => asset.spvId === itemId).map(makeLabel);
695
- }
696
- }
697
- function makeDependentTransactionsList(tableName, itemId, transactions) {
698
- const makeLabel = (t, index) => ({
699
- id: t.id,
700
- label: `Transaction #${index + 1}`
701
- });
702
- switch (tableName) {
703
- case "ASSET": return transactions.filter((t) => t.fixedIncomeTransaction?.assetId === itemId).map(makeLabel);
704
- case "ACCOUNT": return transactions.filter((t) => t.cashTransaction.accountId === itemId || t.fixedIncomeTransaction?.accountId === itemId).map(makeLabel);
705
- case "SERVICE_PROVIDER_FEE_TYPE": return transactions.filter((t) => t.fees?.some((f) => f.serviceProviderFeeTypeId === itemId)).map(makeLabel);
706
- }
707
- }
708
- //#endregion
709
- //#region src/rwa/components/cash-balance-change.tsx
710
- function CashBalanceChange(props) {
711
- const { control } = props;
712
- const cashAmount = useWatch({
713
- control,
714
- name: "cashAmount"
715
- });
716
- const cashBalanceChange = calculateCashBalanceChange(useWatch({
717
- control,
718
- name: "type"
719
- }), cashAmount, useWatch({
720
- control,
721
- name: "fees"
722
- }));
723
- return /* @__PURE__ */ jsxs("div", {
724
- className: "flex items-center justify-between border-t border-gray-300 bg-gray-100 p-3 font-semibold text-gray-800",
725
- children: [
726
- /* @__PURE__ */ jsx("div", {
727
- className: "mr-6 text-sm text-gray-600",
728
- children: "Cash Balance Change $USD"
729
- }),
730
- /* @__PURE__ */ jsx("div", { className: "h-px flex-1 border-b border-dashed border-gray-400" }),
731
- /* @__PURE__ */ jsx("div", {
732
- className: "pl-8 text-sm text-gray-900",
733
- children: /* @__PURE__ */ jsx(FormattedNumber, { value: cashBalanceChange })
734
- })
735
- ]
736
- });
737
- }
738
- //#endregion
739
- //#region src/rwa/components/entry-time-label.tsx
740
- function EntryTimeLabel({ control }) {
741
- const value = useWatch({
742
- control,
743
- name: "entryTime"
744
- });
745
- return value ? formatDateForDisplay(new Date(value), true, true) : null;
746
- }
747
- //#endregion
748
- //#region src/rwa/components/text-input.tsx
749
- const RWATableTextInput = /* @__PURE__ */ forwardRef(function RWATableTextInput(props, ref) {
750
- const invalid = props["aria-invalid"] === "true";
751
- const { errorMessage, labelClassName, inputClassName, errorMessageClassName, ...inputProps } = props;
752
- return /* @__PURE__ */ jsxs("label", {
753
- className: labelClassName,
754
- children: [/* @__PURE__ */ jsx("input", {
755
- ...inputProps,
756
- className: twMerge("h-8 w-full rounded-md border border-transparent bg-gray-100 p-3 text-right placeholder:text-gray-500 disabled:bg-transparent disabled:p-0 disabled:text-left", invalid && "border-red-900 outline-red-900 placeholder:text-red-800", inputClassName),
757
- ref,
758
- type: "text"
759
- }), invalid && !!errorMessage ? /* @__PURE__ */ jsx("p", {
760
- className: twMerge("text-sm text-red-900", errorMessageClassName),
761
- role: "alert",
762
- children: errorMessage
763
- }) : null]
764
- });
765
- });
766
- //#endregion
767
- //#region src/rwa/components/number-input.tsx
768
- function RWANumberInput(props) {
769
- const { name, control, currency, rules, errorMessage, errorMessageClassName, numericFormatProps, value: _, onChange: __, ...inputProps } = props;
770
- const { allowNegative = false, decimalScale = 2, thousandSeparator = ",", fixedDecimalScale = true } = numericFormatProps ?? {};
771
- const prefix = currency === "USD" ? "$" : void 0;
772
- const invalid = props["aria-invalid"] === "true";
773
- return /* @__PURE__ */ jsx(Controller, {
774
- control,
775
- name,
776
- render: ({ field: { onChange, value, ref } }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(NumericFormat, {
777
- ...inputProps,
778
- allowNegative,
779
- customInput: RWATableTextInput,
780
- decimalScale,
781
- fixedDecimalScale,
782
- getInputRef: ref,
783
- onValueChange: ({ floatValue }) => onChange(floatValue),
784
- prefix,
785
- thousandSeparator,
786
- value
787
- }), invalid && !!errorMessage ? /* @__PURE__ */ jsx("p", {
788
- className: twMerge("text-sm text-red-900", errorMessageClassName),
789
- role: "alert",
790
- children: errorMessage
791
- }) : null] }),
792
- rules
793
- });
794
- }
795
- //#endregion
796
- //#region src/rwa/components/select.tsx
797
- function RWATableSelect(props) {
798
- const { options, name, control, rules, errorMessage, errorMessageClassName, disabled = false, ...restProps } = props;
799
- const invalid = props["aria-invalid"] === "true";
800
- return /* @__PURE__ */ jsx(Controller, {
801
- control,
802
- name,
803
- render: ({ field: { onChange, onBlur, value } }) => disabled ? /* @__PURE__ */ jsx(Fragment$1, { children: options.find((option) => option.value === value)?.label }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Combobox, {
804
- isDisabled: disabled,
805
- onBlur,
806
- onChange: (option) => !!option && typeof option === "object" && "value" in option && onChange(option.value),
807
- options,
808
- value: options.find((option) => option.value === value) ?? null,
809
- ...restProps
810
- }), invalid && !!errorMessage ? /* @__PURE__ */ jsx("p", {
811
- className: twMerge("text-sm text-red-900", errorMessageClassName),
812
- role: "alert",
813
- children: errorMessage
814
- }) : null] }),
815
- rules
816
- });
817
- }
818
- //#endregion
819
- //#region src/rwa/components/fee-transactions-table.tsx
820
- function FeeTransactionsTable(props) {
821
- const headings = [
822
- "Fees",
823
- "Service Provider",
824
- "Amount",
825
- ""
826
- ];
827
- const { canHaveTransactionFees, serviceProviderFeeTypes, serviceProviderFeeTypeOptions, control, errors, isViewOnly, showCreateServiceProviderFeeTypeModal } = props;
828
- const { fields, append, remove } = useFieldArray({
829
- control,
830
- name: "fees"
831
- });
832
- if (!canHaveTransactionFees) return null;
833
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [fields.length > 0 && /* @__PURE__ */ jsx("div", {
834
- className: "bg-gray-50 pl-5 pt-3",
835
- children: /* @__PURE__ */ jsxs("table", {
836
- className: "w-full border-separate text-xs font-medium",
837
- children: [/* @__PURE__ */ jsx("thead", {
838
- className: "mb-2",
839
- children: /* @__PURE__ */ jsx("tr", { children: headings.map((heading) => /* @__PURE__ */ jsx("th", {
840
- className: twMerge("py-2 text-left font-medium text-gray-600", heading === "Amount" && !isViewOnly && "text-right"),
841
- children: heading
842
- }, heading)) })
843
- }), /* @__PURE__ */ jsx("tbody", { children: fields.map((feeInput, index) => {
844
- return /* @__PURE__ */ jsxs("tr", { children: [
845
- /* @__PURE__ */ jsx("td", { className: "w-52" }),
846
- /* @__PURE__ */ jsx("td", {
847
- className: "w-96",
848
- children: /* @__PURE__ */ jsx(RWATableSelect, {
849
- addItemButtonProps: {
850
- onClick: showCreateServiceProviderFeeTypeModal,
851
- label: "Add Service Provider"
852
- },
853
- "aria-invalid": errors.fees?.[index]?.serviceProviderFeeTypeId ? "true" : "false",
854
- control,
855
- disabled: isViewOnly,
856
- name: `fees.${index}.serviceProviderFeeTypeId`,
857
- options: serviceProviderFeeTypeOptions,
858
- rules: { required: "Service provider is required" }
859
- })
860
- }),
861
- /* @__PURE__ */ jsx("td", {
862
- className: "w-52",
863
- children: /* @__PURE__ */ jsx(RWANumberInput, {
864
- "aria-invalid": errors.fees?.[index]?.amount ? "true" : "false",
865
- control,
866
- currency: "USD",
867
- disabled: isViewOnly,
868
- name: `fees.${index}.amount`,
869
- placeholder: "E.g. $1,000.00",
870
- rules: {
871
- required: "Amount is required",
872
- validate: { positive: (value) => !!value && Number(value) > 0 || "Fee amount must be greater than zero" }
873
- }
874
- })
875
- }),
876
- /* @__PURE__ */ jsx("td", {
877
- className: "",
878
- children: !isViewOnly && /* @__PURE__ */ jsx("button", {
879
- className: "flex items-center",
880
- onClick: () => remove(index),
881
- type: "button",
882
- children: /* @__PURE__ */ jsx(Icon, {
883
- className: "text-gray-900",
884
- name: "Xmark"
885
- })
886
- })
887
- })
888
- ] }, feeInput.id);
889
- }) })]
890
- })
891
- }), !isViewOnly && /* @__PURE__ */ jsxs("button", {
892
- className: "ml-[234px] mt-1 flex w-fit items-center justify-center gap-x-2 rounded-lg bg-white pb-6 text-sm font-semibold text-gray-900",
893
- onClick: () => append({
894
- amount: null,
895
- serviceProviderFeeTypeId: serviceProviderFeeTypes[0]?.id
896
- }),
897
- children: [/* @__PURE__ */ jsx("span", { children: "Add Fee" }), /* @__PURE__ */ jsx(Icon, {
898
- name: "Plus",
899
- size: 16
900
- })]
901
- })] });
902
- }
903
- //#endregion
904
- //#region src/services/viem.ts
905
- function getIsTransaction(hash) {
906
- if (!isHexString(hash)) return false;
907
- return hash.length === 66;
908
- }
909
- function isHexString(value) {
910
- return typeof value === "string" && value.startsWith("0x");
911
- }
912
- //#endregion
913
- //#region src/rwa/components/transaction-reference.tsx
914
- const TransactionReference = /* @__PURE__ */ forwardRef(function TransactionReference(props, ref) {
915
- const { control, disabled } = props;
916
- const value = useWatch({
917
- control,
918
- name: "txRef"
919
- });
920
- const maxLength = 46;
921
- const maybeShortenedValue = typeof value === "string" && value.length >= maxLength ? `${value.slice(0, maxLength)}...` : value;
922
- const isTransaction = getIsTransaction(value);
923
- const tooltipContent = /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", { children: value }), isTransaction ? /* @__PURE__ */ jsx("p", {
924
- className: "mt-2 text-center",
925
- children: /* @__PURE__ */ jsx("a", {
926
- className: "text-blue-900 underline",
927
- href: `https://etherscan.io/tx/${value}`,
928
- children: "View on Etherscan"
929
- })
930
- }) : null] });
931
- if (disabled) return /* @__PURE__ */ jsx(ConnectTooltipProvider, { children: /* @__PURE__ */ jsx(ConnectTooltip, {
932
- content: tooltipContent,
933
- children: /* @__PURE__ */ jsx("span", { children: maybeShortenedValue })
934
- }) });
935
- return /* @__PURE__ */ jsx(RWATableTextInput, {
936
- ...props,
937
- ref
938
- });
939
- });
940
- //#endregion
941
- //#region src/rwa/components/unit-price.tsx
942
- function UnitPrice(props) {
943
- const { control } = props;
944
- const unitPrice = calculateUnitPrice(useWatch({
945
- control,
946
- name: "cashAmount"
947
- }), useWatch({
948
- control,
949
- name: "fixedIncomeAmount"
950
- }));
951
- return /* @__PURE__ */ jsxs("div", {
952
- className: twMerge("mt-1 w-fit", !props.isViewOnly && "ml-auto"),
953
- children: [
954
- /* @__PURE__ */ jsx("span", {
955
- className: "text-gray-600",
956
- children: "Unit Price"
957
- }),
958
- " ",
959
- /* @__PURE__ */ jsx("span", {
960
- className: "text-gray-900",
961
- children: /* @__PURE__ */ jsx(FormattedNumber, {
962
- decimalScale: 6,
963
- value: unitPrice
964
- })
965
- })
966
- ]
967
- });
968
- }
969
- //#endregion
970
- //#region src/rwa/components/modal-context.ts
971
- const ModalContext = /* @__PURE__ */ createContext({
972
- showModal: () => {},
973
- closeModal: () => {}
974
- });
975
- //#endregion
976
- //#region src/rwa/components/use-modal.ts
977
- const useModal = () => {
978
- return useContext(ModalContext);
979
- };
980
- //#endregion
981
- //#region src/rwa/utils/form.ts
982
- function makeFixedIncomeOptionLabel(fixedIncome) {
983
- let label = fixedIncome.name;
984
- if (fixedIncome.ISIN) label += ` - ${fixedIncome.ISIN}`;
985
- if (fixedIncome.CUSIP) label += ` - ${fixedIncome.CUSIP}`;
986
- return label;
987
- }
988
- //#endregion
989
- //#region src/rwa/hooks/useFormInputs.tsx
990
- function useFormInputs(props) {
991
- const { tableName, operation, formState: _formState, tableItem: _tableItem, register: _register, watch: _watch, control: _control } = props;
992
- const { fixedIncomeTypes, spvs, serviceProviderFeeTypes, accounts, fixedIncomes } = useEditorContext();
993
- const { showModal } = useModal();
994
- const showCreateItemModal = useCallback((tableName) => () => {
995
- showModal("createItem", { tableName });
996
- }, [showModal]);
997
- return useMemo(() => {
998
- switch (tableName) {
999
- case tableNames.ASSET: {
1000
- const tableItem = _tableItem;
1001
- const register = _register;
1002
- const { errors } = _formState;
1003
- const control = _control;
1004
- const derivedInputsToDisplay = operation !== "create" && !!tableItem ? [
1005
- {
1006
- label: "Notional",
1007
- Input: () => /* @__PURE__ */ jsx(Fragment$1, { children: handleTableDatum(tableItem.notional) })
1008
- },
1009
- {
1010
- label: "Purchase Date",
1011
- Input: () => /* @__PURE__ */ jsx(Fragment$1, { children: handleTableDatum(tableItem.purchaseDate) })
1012
- },
1013
- {
1014
- label: "Purchase Price",
1015
- Input: () => /* @__PURE__ */ jsx(Fragment$1, { children: handleTableDatum(tableItem.purchasePrice, 6) })
1016
- },
1017
- {
1018
- label: "Purchase Proceeds",
1019
- Input: () => /* @__PURE__ */ jsx(Fragment$1, { children: handleTableDatum(tableItem.purchaseProceeds) })
1020
- }
1021
- ] : [];
1022
- return { inputs: [
1023
- {
1024
- label: "Asset Name",
1025
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1026
- ...register("name", {
1027
- disabled: operation === "view",
1028
- required: "Asset name is required"
1029
- }),
1030
- "aria-invalid": errors.name ? "true" : "false",
1031
- errorMessage: errors.name?.message,
1032
- inputClassName: "text-left",
1033
- placeholder: "E.g. My Asset"
1034
- })
1035
- },
1036
- {
1037
- label: "CUSIP",
1038
- Input: () => operation === "view" ? tableItem?.CUSIP ?? "Not available" : /* @__PURE__ */ jsx(RWATableTextInput, {
1039
- ...register("CUSIP", {
1040
- maxLength: {
1041
- value: 9,
1042
- message: "CUSIP cannot be longer than 9 characters"
1043
- },
1044
- minLength: {
1045
- value: 9,
1046
- message: "CUSIP cannot be shorter than 9 characters"
1047
- },
1048
- pattern: {
1049
- value: /^[a-zA-Z0-9]*$/,
1050
- message: "CUSIP must be alphanumeric"
1051
- }
1052
- }),
1053
- "aria-invalid": errors.CUSIP ? "true" : "false",
1054
- errorMessage: errors.CUSIP?.message,
1055
- placeholder: "E.g. A2345B789"
1056
- })
1057
- },
1058
- {
1059
- label: "ISIN",
1060
- Input: () => operation === "view" ? tableItem?.ISIN ?? "Not available" : /* @__PURE__ */ jsx(RWATableTextInput, {
1061
- ...register("ISIN", {
1062
- maxLength: {
1063
- value: 12,
1064
- message: "ISIN cannot be longer than 12 characters"
1065
- },
1066
- minLength: {
1067
- value: 12,
1068
- message: "ISIN cannot be shorter than 12 characters"
1069
- },
1070
- pattern: {
1071
- value: /^[a-zA-Z0-9]*$/,
1072
- message: "ISIN must be alphanumeric"
1073
- }
1074
- }),
1075
- "aria-invalid": errors.ISIN ? "true" : "false",
1076
- errorMessage: errors.ISIN?.message,
1077
- placeholder: "E.g. 123456789ABC"
1078
- })
1079
- },
1080
- {
1081
- label: "Maturity",
1082
- Input: () => /* @__PURE__ */ jsx("input", {
1083
- className: "h-8 w-full rounded-md bg-gray-100 px-3 disabled:bg-transparent disabled:p-0",
1084
- step: 1,
1085
- type: "date",
1086
- ...register("maturity", { disabled: operation === "view" })
1087
- }),
1088
- inputLabel: tableItem?.maturity ? formatDateForDisplay(tableItem.maturity, true) : null
1089
- },
1090
- {
1091
- label: "Asset Type",
1092
- Input: () => /* @__PURE__ */ jsx(RWATableSelect, {
1093
- addItemButtonProps: {
1094
- onClick: showCreateItemModal("ASSET"),
1095
- label: "Create Fixed Income Type"
1096
- },
1097
- "aria-invalid": errors.fixedIncomeTypeId ? "true" : "false",
1098
- control,
1099
- disabled: operation === "view",
1100
- errorMessage: errors.fixedIncomeTypeId?.message,
1101
- name: "fixedIncomeTypeId",
1102
- options: fixedIncomeTypes.map((t) => ({
1103
- ...t,
1104
- value: t.id,
1105
- label: t.name
1106
- })),
1107
- rules: { required: "Asset type is required" }
1108
- })
1109
- },
1110
- {
1111
- label: "SPV",
1112
- Input: () => /* @__PURE__ */ jsx(RWATableSelect, {
1113
- addItemButtonProps: {
1114
- onClick: showCreateItemModal("SPV"),
1115
- label: "Create SPV"
1116
- },
1117
- "aria-invalid": errors.spvId ? "true" : "false",
1118
- control,
1119
- disabled: operation === "view",
1120
- errorMessage: errors.spvId?.message,
1121
- name: "spvId",
1122
- options: spvs.map((t) => ({
1123
- ...t,
1124
- value: t.id,
1125
- label: t.name
1126
- })),
1127
- rules: { required: "SPV is required" }
1128
- })
1129
- },
1130
- ...derivedInputsToDisplay
1131
- ] };
1132
- }
1133
- case tableNames.TRANSACTION: {
1134
- const register = _register;
1135
- const watch = _watch;
1136
- const { errors } = _formState;
1137
- const control = _control;
1138
- const type = watch("type");
1139
- const isFeesTransaction = !!type && feesTransactions.includes(type);
1140
- const isAssetTransaction = !!type && assetGroupTransactions.includes(type);
1141
- const canHaveTransactionFees = !isFeesTransaction;
1142
- const transactionTypeOptions = allGroupTransactionTypes.map((type) => ({
1143
- label: groupTransactionTypeLabels[type],
1144
- value: type
1145
- }));
1146
- const fixedIncomeOptions = fixedIncomes.map((fixedIncome) => ({
1147
- label: makeFixedIncomeOptionLabel(fixedIncome),
1148
- value: fixedIncome.id
1149
- }));
1150
- const serviceProviderFeeTypeOptions = serviceProviderFeeTypes.map((spft) => ({
1151
- label: `${spft.name} — ${spft.feeType} — ${accounts.find((account) => account.id === spft.accountId)?.reference}`,
1152
- value: spft.id
1153
- }));
1154
- return {
1155
- inputs: [
1156
- {
1157
- label: "Transaction Type",
1158
- Input: () => /* @__PURE__ */ jsx(RWATableSelect, {
1159
- "aria-invalid": errors.type ? "true" : "false",
1160
- control,
1161
- disabled: operation === "view",
1162
- errorMessage: errors.type?.message,
1163
- name: "type",
1164
- options: transactionTypeOptions,
1165
- rules: { required: "Transaction type is required" }
1166
- })
1167
- },
1168
- {
1169
- label: "Entry Time",
1170
- Input: () => /* @__PURE__ */ jsx("input", {
1171
- className: "h-8 w-full rounded-md bg-gray-100 px-3 disabled:bg-transparent disabled:p-0",
1172
- step: 1,
1173
- type: "datetime-local",
1174
- ...register("entryTime", {
1175
- disabled: operation === "view",
1176
- required: "Entry time is required"
1177
- })
1178
- }),
1179
- inputLabel: /* @__PURE__ */ jsx(EntryTimeLabel, { control })
1180
- },
1181
- isFeesTransaction ? {
1182
- label: "Service Provider",
1183
- Input: () => /* @__PURE__ */ jsx(RWATableSelect, {
1184
- addItemButtonProps: {
1185
- onClick: showCreateItemModal("SERVICE_PROVIDER_FEE_TYPE"),
1186
- label: "Add Service Provider"
1187
- },
1188
- control,
1189
- disabled: operation === "view",
1190
- name: "serviceProviderFeeTypeId",
1191
- options: serviceProviderFeeTypeOptions
1192
- })
1193
- } : null,
1194
- isAssetTransaction ? {
1195
- label: "Asset name",
1196
- Input: () => /* @__PURE__ */ jsx(RWATableSelect, {
1197
- addItemButtonProps: {
1198
- onClick: showCreateItemModal("ASSET"),
1199
- label: "Create Asset"
1200
- },
1201
- "aria-invalid": errors.type ? "true" : "false",
1202
- control,
1203
- disabled: operation === "view",
1204
- errorMessage: errors.type?.message,
1205
- name: "fixedIncomeId",
1206
- options: fixedIncomeOptions,
1207
- rules: { required: "Asset name is required" }
1208
- })
1209
- } : void 0,
1210
- isAssetTransaction ? {
1211
- label: "Quantity",
1212
- Input: () => /* @__PURE__ */ jsx(RWANumberInput, {
1213
- "aria-invalid": errors.fixedIncomeAmount ? "true" : "false",
1214
- control,
1215
- disabled: operation === "view",
1216
- errorMessage: errors.fixedIncomeAmount?.message,
1217
- name: "fixedIncomeAmount",
1218
- placeholder: "E.g. 1,000.00",
1219
- rules: {
1220
- required: "Quantity is required",
1221
- validate: { positive: (value) => !!value && Number(value) > 0 || "Asset proceeds must be greater than zero" }
1222
- }
1223
- })
1224
- } : void 0,
1225
- {
1226
- label: isAssetTransaction ? "Asset Proceeds" : "Cash Amount",
1227
- Input: () => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(RWANumberInput, {
1228
- "aria-invalid": errors.cashAmount ? "true" : "false",
1229
- control,
1230
- currency: "USD",
1231
- disabled: operation === "view",
1232
- errorMessage: errors.cashAmount?.message,
1233
- name: "cashAmount",
1234
- placeholder: "E.g. $1,000.00",
1235
- rules: {
1236
- required: "Asset proceeds is required",
1237
- validate: { positive: (value) => !!value && Number(value) > 0 || "Asset proceeds must be greater than zero" }
1238
- }
1239
- }), isAssetTransaction ? /* @__PURE__ */ jsx(UnitPrice, {
1240
- control,
1241
- isViewOnly: operation === "view"
1242
- }) : null] })
1243
- },
1244
- {
1245
- label: "Transaction reference",
1246
- Input: () => /* @__PURE__ */ jsx(TransactionReference, {
1247
- ...register("txRef", { disabled: operation === "view" }),
1248
- "aria-invalid": errors.txRef ? "true" : "false",
1249
- control,
1250
- errorMessage: errors.txRef?.message,
1251
- placeholder: "E.g. 0x123..."
1252
- })
1253
- }
1254
- ].filter(Boolean),
1255
- additionalInputs: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(FeeTransactionsTable, {
1256
- canHaveTransactionFees,
1257
- control,
1258
- errors,
1259
- isViewOnly: operation === "view",
1260
- serviceProviderFeeTypeOptions,
1261
- serviceProviderFeeTypes,
1262
- showCreateServiceProviderFeeTypeModal: showCreateItemModal("SERVICE_PROVIDER_FEE_TYPE")
1263
- }), /* @__PURE__ */ jsx(CashBalanceChange, { control })] })
1264
- };
1265
- }
1266
- case tableNames.ACCOUNT: {
1267
- const register = _register;
1268
- const { errors } = _formState;
1269
- return { inputs: [{
1270
- label: "Account Label",
1271
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1272
- ...register("label", {
1273
- disabled: operation === "view",
1274
- required: "Account label is required"
1275
- }),
1276
- "aria-invalid": errors.label?.type === "required" ? "true" : "false",
1277
- errorMessage: errors.label?.message,
1278
- placeholder: "E.g. My Label"
1279
- })
1280
- }, {
1281
- label: "Account Reference",
1282
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1283
- ...register("reference", {
1284
- disabled: operation === "view",
1285
- required: "Account reference is required"
1286
- }),
1287
- "aria-invalid": errors.reference?.type === "required" ? "true" : "false",
1288
- errorMessage: errors.reference?.message,
1289
- placeholder: "E.g. bank account number or ETH address"
1290
- })
1291
- }] };
1292
- }
1293
- case tableNames.SPV: {
1294
- const register = _register;
1295
- const { errors } = _formState;
1296
- return { inputs: [{
1297
- label: "SPV name",
1298
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1299
- ...register("name", {
1300
- disabled: operation === "view",
1301
- required: "SPV name is required"
1302
- }),
1303
- "aria-invalid": errors.name?.type === "required" ? "true" : "false",
1304
- errorMessage: errors.name?.message,
1305
- placeholder: "E.g. My SPV name"
1306
- })
1307
- }] };
1308
- }
1309
- case tableNames.FIXED_INCOME_TYPE: {
1310
- const register = _register;
1311
- const { errors } = _formState;
1312
- return { inputs: [{
1313
- label: "Fixed Income Type Name",
1314
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1315
- ...register("name", {
1316
- disabled: operation === "view",
1317
- required: "Fixed Income Type name is required"
1318
- }),
1319
- "aria-invalid": errors.name?.type === "required" ? "true" : "false",
1320
- errorMessage: errors.name?.message,
1321
- placeholder: "E.g. My Fixed Income Type name"
1322
- })
1323
- }] };
1324
- }
1325
- case tableNames.SERVICE_PROVIDER_FEE_TYPE: {
1326
- const register = _register;
1327
- const { errors } = _formState;
1328
- const control = _control;
1329
- const makeAccountLabel = (account) => {
1330
- return `${account.label} (${account.reference})`;
1331
- };
1332
- const makeAccountOptions = (accounts) => {
1333
- return accounts.map((account) => ({
1334
- ...account,
1335
- value: account.id,
1336
- label: makeAccountLabel(account)
1337
- }));
1338
- };
1339
- return { inputs: [
1340
- {
1341
- label: "Service Provider Name",
1342
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1343
- ...register("name", {
1344
- disabled: operation === "view",
1345
- required: "Service provider name is required"
1346
- }),
1347
- "aria-invalid": errors.name?.type === "required" ? "true" : "false",
1348
- errorMessage: errors.name?.message,
1349
- placeholder: "E.g. My Service Provider"
1350
- })
1351
- },
1352
- {
1353
- label: "Fee Type",
1354
- Input: () => /* @__PURE__ */ jsx(RWATableTextInput, {
1355
- ...register("feeType", {
1356
- disabled: operation === "view",
1357
- required: "Fee type is required"
1358
- }),
1359
- "aria-invalid": errors.name?.type === "required" ? "true" : "false",
1360
- errorMessage: errors.name?.message,
1361
- placeholder: "E.g. My Fee Type"
1362
- })
1363
- },
1364
- {
1365
- label: "Account",
1366
- Input: () => /* @__PURE__ */ jsx(RWATableSelect, {
1367
- addItemButtonProps: {
1368
- onClick: showCreateItemModal("ACCOUNT"),
1369
- label: "Create Account"
1370
- },
1371
- "aria-invalid": errors.accountId ? "true" : "false",
1372
- control,
1373
- disabled: operation === "view",
1374
- errorMessage: errors.accountId?.message,
1375
- name: "accountId",
1376
- options: makeAccountOptions(accounts),
1377
- rules: { required: "Account is required" }
1378
- })
1379
- }
1380
- ] };
1381
- }
1382
- }
1383
- }, [
1384
- _formState,
1385
- _control,
1386
- _register,
1387
- _tableItem,
1388
- _watch,
1389
- accounts,
1390
- fixedIncomeTypes,
1391
- fixedIncomes,
1392
- operation,
1393
- serviceProviderFeeTypes,
1394
- showCreateItemModal,
1395
- spvs,
1396
- tableName
1397
- ]);
1398
- }
1399
- //#endregion
1400
- //#region src/rwa/hooks/useDefaultFormValues.ts
1401
- function useDefaultFormValues(args) {
1402
- const { tableName, tableItem, fixedIncomeTypes, spvs, accounts } = args;
1403
- return useMemo(() => {
1404
- if (!tableItem) switch (tableName) {
1405
- case tableNames.ASSET: return {
1406
- fixedIncomeTypeId: fixedIncomeTypes[0]?.id ?? null,
1407
- spvId: spvs[0]?.id ?? null,
1408
- name: null,
1409
- maturity: null,
1410
- ISIN: null,
1411
- CUSIP: null,
1412
- coupon: null
1413
- };
1414
- case tableNames.TRANSACTION: return {
1415
- type: allGroupTransactionTypes[0],
1416
- entryTime: isoDateStringToDateInput((/* @__PURE__ */ new Date()).toISOString(), true),
1417
- cashAmount: null,
1418
- fixedIncomeId: null,
1419
- fixedIncomeAmount: null,
1420
- serviceProviderFeeTypeId: null,
1421
- fees: null,
1422
- txRef: null
1423
- };
1424
- case tableNames.SPV: return { name: null };
1425
- case tableNames.SERVICE_PROVIDER_FEE_TYPE: return {
1426
- name: null,
1427
- feeType: null,
1428
- accountId: accounts[0]?.id ?? null
1429
- };
1430
- case tableNames.FIXED_INCOME_TYPE: return { name: null };
1431
- case tableNames.ACCOUNT: return {
1432
- label: null,
1433
- reference: null
1434
- };
1435
- }
1436
- switch (tableName) {
1437
- case tableNames.ASSET: {
1438
- const item = tableItem;
1439
- return {
1440
- id: item.id,
1441
- fixedIncomeTypeId: item.fixedIncomeTypeId,
1442
- spvId: item.spvId,
1443
- name: item.name,
1444
- maturity: item.maturity ? isoDateStringToDateInput(item.maturity) : null,
1445
- ISIN: item.ISIN,
1446
- CUSIP: item.CUSIP,
1447
- coupon: item.coupon
1448
- };
1449
- }
1450
- case tableNames.TRANSACTION: {
1451
- const item = tableItem;
1452
- return {
1453
- id: item.id,
1454
- type: item.type,
1455
- entryTime: item.entryTime ? isoDateStringToDateInput(item.entryTime, true) : null,
1456
- cashAmount: item.cashTransaction.amount ?? null,
1457
- fixedIncomeId: item.fixedIncomeTransaction?.assetId ?? null,
1458
- fixedIncomeAmount: item.fixedIncomeTransaction?.amount ?? null,
1459
- serviceProviderFeeTypeId: item.serviceProviderFeeTypeId ?? null,
1460
- fees: item.fees ?? null,
1461
- txRef: item.txRef ?? null
1462
- };
1463
- }
1464
- case tableNames.SPV: {
1465
- const item = tableItem;
1466
- return {
1467
- id: item.id,
1468
- name: item.name
1469
- };
1470
- }
1471
- case tableNames.SERVICE_PROVIDER_FEE_TYPE: {
1472
- const item = tableItem;
1473
- return {
1474
- id: item.id,
1475
- name: item.name,
1476
- feeType: item.feeType,
1477
- accountId: item.accountId
1478
- };
1479
- }
1480
- case tableNames.FIXED_INCOME_TYPE: {
1481
- const item = tableItem;
1482
- return {
1483
- id: item.id,
1484
- name: item.name
1485
- };
1486
- }
1487
- case tableNames.ACCOUNT: {
1488
- const item = tableItem;
1489
- return {
1490
- id: item.id,
1491
- label: item.label,
1492
- reference: item.reference
1493
- };
1494
- }
1495
- }
1496
- }, [
1497
- accounts,
1498
- fixedIncomeTypes,
1499
- spvs,
1500
- tableItem,
1501
- tableName
1502
- ]);
1503
- }
1504
- //#endregion
1505
- //#region src/rwa/hooks/useSubmit.ts
1506
- function useWrappedForm(defaultValues) {
1507
- return useForm({ defaultValues });
1508
- }
1509
- function useSubmit(props) {
1510
- const { operation, tableName, tableItem } = props;
1511
- const { handleAction, fixedIncomeTypes, spvs, accounts } = useEditorContext();
1512
- const defaultValues = useDefaultFormValues({
1513
- tableName,
1514
- tableItem,
1515
- fixedIncomeTypes,
1516
- spvs,
1517
- accounts
1518
- });
1519
- const action = operation === "create" ? "CREATE" : "EDIT";
1520
- const formValues = defaultValues;
1521
- const { register, handleSubmit, reset, watch, control, formState } = useWrappedForm(formValues);
1522
- useEffect(() => {
1523
- reset(formValues);
1524
- }, [formValues, reset]);
1525
- const submit = handleSubmit(useCallback((payload) => {
1526
- handleAction({
1527
- type: `${action}_${tableName}`,
1528
- payload
1529
- });
1530
- }, [
1531
- action,
1532
- handleAction,
1533
- tableName
1534
- ]));
1535
- return useMemo(() => ({
1536
- register,
1537
- reset,
1538
- watch,
1539
- control,
1540
- formState,
1541
- submit
1542
- }), [
1543
- control,
1544
- formState,
1545
- register,
1546
- reset,
1547
- submit,
1548
- watch
1549
- ]);
1550
- }
1551
- //#endregion
1552
- //#region src/rwa/hooks/useTableForm.tsx
1553
- function useTableForm(props) {
1554
- const { operation, tableName, tableItem } = props;
1555
- const { submit, reset, register, control, formState, watch } = useSubmit({
1556
- operation,
1557
- tableName,
1558
- tableItem
1559
- });
1560
- const formInputs = useFormInputs({
1561
- formState,
1562
- operation,
1563
- control,
1564
- watch,
1565
- tableItem,
1566
- tableName,
1567
- register
1568
- });
1569
- return useMemo(() => {
1570
- return {
1571
- submit,
1572
- reset,
1573
- register,
1574
- control,
1575
- formInputs,
1576
- formState
1577
- };
1578
- }, [
1579
- submit,
1580
- reset,
1581
- register,
1582
- control,
1583
- formInputs,
1584
- formState
1585
- ]);
1586
- }
1587
- //#endregion
1588
- //#region src/rwa/components/button.tsx
1589
- const RWAButton = (props) => {
1590
- return /* @__PURE__ */ jsx(PowerhouseButton, {
1591
- color: "light",
1592
- size: "small",
1593
- ...mergeClassNameProps(props, "border border-solid border-gray-300 bg-white px-3 py-1 text-sm text-gray-900"),
1594
- children: props.children
1595
- });
1596
- };
1597
- //#endregion
1598
- //#region src/rwa/components/form-inputs.tsx
1599
- function FormInputs(props) {
1600
- const { inputs } = props;
1601
- return /* @__PURE__ */ jsx("div", {
1602
- className: "rounded-md bg-white text-xs font-medium",
1603
- children: inputs.map(({ label, Input, inputLabel }, index) => /* @__PURE__ */ jsxs("div", {
1604
- className: twJoin("grid min-h-11 grid-cols-[208px,380px] items-center px-6 text-gray-600 last:rounded-b-md", index % 2 !== 0 && "bg-gray-50"),
1605
- children: [/* @__PURE__ */ jsx("div", { children: label }), /* @__PURE__ */ jsxs("div", {
1606
- className: "h-max py-2 text-gray-900",
1607
- children: [/* @__PURE__ */ jsx(Input, {}), inputLabel ? /* @__PURE__ */ jsx("div", {
1608
- className: "text-left text-gray-500",
1609
- children: inputLabel
1610
- }) : null]
1611
- }, index)]
1612
- }, label))
1613
- });
1614
- }
1615
- //#endregion
1616
- //#region src/rwa/components/item-details.tsx
1617
- const ItemDetails = /* @__PURE__ */ memo(function ItemDetails(props) {
1618
- const { tableName } = props;
1619
- const { showModal, closeModal } = useModal();
1620
- const { selectedTableItem, operation, viewItem, editItem, clearSelected, handleAction, isAllowedToCreateDocuments, isAllowedToEditDocuments, principalLenderAccountId } = useEditorContext();
1621
- const dependentItemProps = useDependentItemProps(tableName, selectedTableItem?.id);
1622
- const hasDependentItems = dependentItemProps.some((p) => p.dependentItems.length > 0);
1623
- const isEditOperation = operation === "edit";
1624
- const isCreateOperation = operation === "create";
1625
- const isViewOperation = operation === "view";
1626
- const isAllowedToCreateOrEdit = isAllowedToCreateDocuments || isAllowedToEditDocuments;
1627
- const isAllowedToDeleteItem = !(tableName === "ACCOUNT" && selectedTableItem?.id === principalLenderAccountId);
1628
- const showCancelButton = !isViewOperation && isAllowedToCreateOrEdit;
1629
- const showSubmitButton = !isViewOperation && isAllowedToCreateOrEdit;
1630
- const showDeleteButton = isEditOperation && isAllowedToEditDocuments && isAllowedToDeleteItem;
1631
- const showEditButton = isViewOperation && isAllowedToEditDocuments;
1632
- const showCloseButton = isViewOperation;
1633
- const tableLabel = tableLabels[tableName];
1634
- const { submit, reset, formInputs: { inputs, additionalInputs } } = useTableForm({
1635
- tableName,
1636
- tableItem: selectedTableItem,
1637
- operation
1638
- });
1639
- const handleClose = useCallback(() => {
1640
- reset();
1641
- clearSelected();
1642
- }, [clearSelected, reset]);
1643
- const handleCancel = useCallback(() => {
1644
- if (operation === "edit" && !!selectedTableItem) {
1645
- viewItem(selectedTableItem, tableName);
1646
- return;
1647
- }
1648
- handleClose();
1649
- }, [
1650
- handleClose,
1651
- operation,
1652
- selectedTableItem,
1653
- tableName,
1654
- viewItem
1655
- ]);
1656
- const showDeleteModal = useCallback(() => {
1657
- if (!isAllowedToDeleteItem || !hasDependentItems) return;
1658
- showModal("deleteItem", {
1659
- tableName,
1660
- dependentItemProps
1661
- });
1662
- }, [
1663
- isAllowedToDeleteItem,
1664
- hasDependentItems,
1665
- showModal,
1666
- tableName,
1667
- dependentItemProps
1668
- ]);
1669
- const handleDelete = useCallback(() => {
1670
- if (!selectedTableItem) return;
1671
- if (hasDependentItems) {
1672
- showDeleteModal();
1673
- return;
1674
- }
1675
- handleAction({
1676
- type: `DELETE_${tableName}`,
1677
- payload: selectedTableItem
1678
- });
1679
- clearSelected();
1680
- closeModal();
1681
- }, [
1682
- selectedTableItem,
1683
- hasDependentItems,
1684
- tableName,
1685
- handleAction,
1686
- clearSelected,
1687
- closeModal,
1688
- showDeleteModal
1689
- ]);
1690
- const onEditButtonClick = useCallback(() => {
1691
- if (!selectedTableItem) return;
1692
- editItem(selectedTableItem, tableName);
1693
- }, [
1694
- selectedTableItem,
1695
- editItem,
1696
- tableName
1697
- ]);
1698
- const closeButton = /* @__PURE__ */ jsx(RWAButton, {
1699
- className: "text-gray-600",
1700
- onClick: handleClose,
1701
- children: "Close"
1702
- });
1703
- const cancelButton = /* @__PURE__ */ jsx(RWAButton, {
1704
- className: "text-gray-600",
1705
- onClick: handleCancel,
1706
- children: "Cancel"
1707
- });
1708
- const submitButton = /* @__PURE__ */ jsx(RWAButton, {
1709
- icon: /* @__PURE__ */ jsx(Icon, {
1710
- name: "Save",
1711
- size: 16
1712
- }),
1713
- iconPosition: "right",
1714
- onClick: submit,
1715
- children: isCreateOperation ? "Save" : "Save Edits"
1716
- });
1717
- const deleteButton = /* @__PURE__ */ jsx("button", {
1718
- onClick: handleDelete,
1719
- children: /* @__PURE__ */ jsx(Icon, {
1720
- className: "ml-3 text-red-800",
1721
- name: "Trash",
1722
- size: 22
1723
- })
1724
- });
1725
- const editButton = /* @__PURE__ */ jsxs(RWAButton, {
1726
- icon: /* @__PURE__ */ jsx(Icon, {
1727
- name: "Pencil",
1728
- size: 16
1729
- }),
1730
- iconPosition: "right",
1731
- onClick: onEditButtonClick,
1732
- children: ["Edit ", tableLabel]
1733
- });
1734
- return /* @__PURE__ */ jsxs("div", {
1735
- className: "flex flex-col rounded-md border border-gray-300 bg-white",
1736
- children: [
1737
- /* @__PURE__ */ jsxs("div", {
1738
- className: "flex justify-between rounded-t-md border-b border-gray-300 bg-gray-100 p-3 font-semibold text-gray-800",
1739
- children: [/* @__PURE__ */ jsx("div", {
1740
- className: "flex items-center",
1741
- children: selectedTableItem?.itemNumber ? `${tableLabel} #${selectedTableItem.itemNumber}` : `New ${tableLabel}`
1742
- }), /* @__PURE__ */ jsxs("div", {
1743
- className: "flex gap-x-2",
1744
- children: [
1745
- showCancelButton ? cancelButton : null,
1746
- showCloseButton ? closeButton : null,
1747
- showSubmitButton ? submitButton : null,
1748
- showDeleteButton ? deleteButton : null,
1749
- showEditButton ? editButton : null
1750
- ]
1751
- })]
1752
- }),
1753
- /* @__PURE__ */ jsx(FormInputs, { inputs }),
1754
- additionalInputs
1755
- ]
1756
- });
1757
- });
1758
- //#endregion
1759
- //#region src/rwa/constants/columns.ts
1760
- const columnsByTableName = {
1761
- ASSET: [
1762
- {
1763
- key: "name",
1764
- label: "Name",
1765
- allowSorting: true
1766
- },
1767
- {
1768
- key: "purchaseDate",
1769
- label: "Purchase Date",
1770
- allowSorting: true
1771
- },
1772
- {
1773
- key: "maturity",
1774
- label: "Maturity",
1775
- allowSorting: true,
1776
- displayTime: false
1777
- },
1778
- {
1779
- key: "notional",
1780
- label: "Notional",
1781
- allowSorting: true,
1782
- isNumberColumn: true
1783
- },
1784
- {
1785
- key: "currentValue",
1786
- label: "Current Value",
1787
- allowSorting: true,
1788
- isNumberColumn: true
1789
- },
1790
- {
1791
- key: "purchasePrice",
1792
- label: "Purchase Price",
1793
- allowSorting: true,
1794
- isNumberColumn: true,
1795
- decimalScale: 6
1796
- },
1797
- {
1798
- key: "purchaseProceeds",
1799
- label: "Purchase Proceeds",
1800
- allowSorting: true,
1801
- isNumberColumn: true
1802
- },
1803
- {
1804
- key: "salesProceeds",
1805
- label: "Sales Proceeds",
1806
- allowSorting: true,
1807
- isNumberColumn: true
1808
- },
1809
- {
1810
- key: "totalDiscount",
1811
- label: "Total Discount",
1812
- allowSorting: true,
1813
- isNumberColumn: true
1814
- },
1815
- {
1816
- key: "realizedSurplus",
1817
- label: "Realized Surplus",
1818
- allowSorting: true,
1819
- isNumberColumn: true
1820
- }
1821
- ],
1822
- TRANSACTION: [
1823
- {
1824
- key: "typeLabel",
1825
- label: "Type",
1826
- allowSorting: true
1827
- },
1828
- {
1829
- key: "entryTime",
1830
- label: "Entry Time",
1831
- allowSorting: true
1832
- },
1833
- {
1834
- key: "asset",
1835
- label: "Asset",
1836
- allowSorting: true
1837
- },
1838
- {
1839
- key: "quantity",
1840
- label: "Quantity",
1841
- allowSorting: true,
1842
- isNumberColumn: true
1843
- },
1844
- {
1845
- key: "cashAmount",
1846
- label: "Cash Amount ($)",
1847
- allowSorting: true,
1848
- isNumberColumn: true
1849
- },
1850
- {
1851
- key: "totalFees",
1852
- label: "Total Fees ($)",
1853
- allowSorting: true,
1854
- isNumberColumn: true
1855
- },
1856
- {
1857
- key: "cashBalanceChange",
1858
- label: "Cash Balance Change ($)",
1859
- allowSorting: true,
1860
- isNumberColumn: true
1861
- }
1862
- ],
1863
- FIXED_INCOME_TYPE: [{
1864
- key: "name",
1865
- label: "Name",
1866
- allowSorting: true
1867
- }],
1868
- SPV: [{
1869
- key: "name",
1870
- label: "Name",
1871
- allowSorting: true
1872
- }],
1873
- SERVICE_PROVIDER_FEE_TYPE: [
1874
- {
1875
- key: "name",
1876
- label: "Name",
1877
- allowSorting: true
1878
- },
1879
- {
1880
- key: "feeType",
1881
- label: "Fee Type",
1882
- allowSorting: true
1883
- },
1884
- {
1885
- key: "accountName",
1886
- label: "Account Name",
1887
- allowSorting: true
1888
- },
1889
- {
1890
- key: "accountReference",
1891
- label: "Account Reference",
1892
- allowSorting: true
1893
- }
1894
- ],
1895
- ACCOUNT: [{
1896
- key: "label",
1897
- label: "Label",
1898
- allowSorting: true
1899
- }, {
1900
- key: "reference",
1901
- label: "Reference",
1902
- allowSorting: true
1903
- }]
1904
- };
1905
- //#endregion
1906
- //#region src/rwa/hooks/useColumnPriority.ts
1907
- /**
1908
- * Hook to handle dropping columns for smaller screens.
1909
- *
1910
- * @param columns - Array of columns to display, column must satisfy TableColumn. The columns will be displayed in the order they are provided.
1911
- * @param columnCountByTableWidth - Object that specifies how many columns to show at different screen widths
1912
- * @param tableContainerRef - Ref to the table container element
1913
- * @param hasIndexColumn - When true, adds an "index" column with the index of the row as the _first column_. This column is exempt from being dropped.
1914
- * @param hasMoreDetailsColumn - When true, adds a "more details" column as the _last column_. This column is exempt from being dropped. This column has no header label by default.
1915
- */
1916
- function useColumnPriority(props) {
1917
- const { columnCountByTableWidth, tableContainerRef, columns, hasItemNumberColumn = true, hasMoreDetailsColumn = true } = props;
1918
- const [parentWidth, setParentWidth] = useState(0);
1919
- const indexColumn = useMemo(() => hasItemNumberColumn ? {
1920
- key: "itemNumber",
1921
- label: "#",
1922
- allowSorting: true,
1923
- isSpecialColumn: true
1924
- } : void 0, [hasItemNumberColumn]);
1925
- const moreDetailsColumn = useMemo(() => hasMoreDetailsColumn ? {
1926
- key: "moreDetails",
1927
- label: "",
1928
- isSpecialColumn: true
1929
- } : void 0, [hasMoreDetailsColumn]);
1930
- const [columnsToShow, setColumnsToShow] = useState([]);
1931
- const handleResize = useCallback(() => {
1932
- if (tableContainerRef.current?.parentElement) setParentWidth(tableContainerRef.current.parentElement.offsetWidth);
1933
- }, [tableContainerRef]);
1934
- const handleDropColumns = useCallback(() => {
1935
- const columnCount = getColumnCount(parentWidth, columnCountByTableWidth);
1936
- setColumnsToShow([
1937
- indexColumn,
1938
- ...columns?.slice(0, columnCount) ?? [],
1939
- moreDetailsColumn
1940
- ].filter(Boolean));
1941
- }, [
1942
- parentWidth,
1943
- columns,
1944
- columnCountByTableWidth,
1945
- indexColumn,
1946
- moreDetailsColumn
1947
- ]);
1948
- useEffect(() => {
1949
- handleResize();
1950
- window.addEventListener("resize", handleResize);
1951
- return () => window.removeEventListener("resize", handleResize);
1952
- }, [handleResize]);
1953
- useEffect(() => {
1954
- handleDropColumns();
1955
- }, [handleDropColumns, parentWidth]);
1956
- return useMemo(() => columnsToShow, [columnsToShow]);
1957
- }
1958
- function getColumnCount(parentElementWidth, columnCountByTableWidth) {
1959
- let closestKey = 1520;
1960
- let smallestDifference = Infinity;
1961
- Object.keys(columnCountByTableWidth).forEach((columnWidthKey) => {
1962
- const columnWidth = parseInt(columnWidthKey);
1963
- const difference = Math.abs(parentElementWidth - columnWidth);
1964
- if (difference < smallestDifference) {
1965
- smallestDifference = difference;
1966
- closestKey = parseInt(columnWidthKey);
1967
- }
1968
- });
1969
- return columnCountByTableWidth[closestKey];
1970
- }
1971
- //#endregion
1972
- //#region src/rwa/hooks/useTableHeight.ts
1973
- const defaultRowHeight = 34;
1974
- const defaultHeaderHeight = 42;
1975
- const defaultTwentyRowsPlusHeaderHeight = defaultRowHeight * 20 + defaultHeaderHeight;
1976
- function useTableHeight(props) {
1977
- const { selectedItemNumber, tableContainerRef, rowRefs, headerRef, hasSpecialLastRow = false } = props;
1978
- const [maxHeight, setMaxHeight] = useState(`${defaultTwentyRowsPlusHeaderHeight}px`);
1979
- const selectedRowNumber = selectedItemNumber ? selectedItemNumber - 1 + (hasSpecialLastRow ? 1 : 0) : void 0;
1980
- const rowHeight = rowRefs.current[1]?.offsetHeight ?? defaultRowHeight;
1981
- const headerHeight = headerRef.current?.offsetHeight ?? defaultHeaderHeight;
1982
- const updateTableHeight = useCallback(() => {
1983
- if (selectedRowNumber === void 0) {
1984
- setMaxHeight(`${rowHeight * 20 + headerHeight}px`);
1985
- return;
1986
- }
1987
- const tableContainerRect = tableContainerRef.current?.getBoundingClientRect();
1988
- const rowRect = rowRefs.current[selectedRowNumber]?.getBoundingClientRect();
1989
- if (rowRect && tableContainerRect) setMaxHeight(`${rowRect.bottom - tableContainerRect.top}px`);
1990
- }, [
1991
- headerHeight,
1992
- rowHeight,
1993
- rowRefs,
1994
- selectedRowNumber,
1995
- tableContainerRef
1996
- ]);
1997
- useEffect(() => {
1998
- updateTableHeight();
1999
- }, [updateTableHeight]);
2000
- useEffect(() => {
2001
- const handleScroll = () => {
2002
- updateTableHeight();
2003
- };
2004
- const tableContainerElement = tableContainerRef.current;
2005
- if (tableContainerElement) tableContainerElement.addEventListener("scroll", handleScroll);
2006
- return () => {
2007
- if (tableContainerElement) tableContainerElement.removeEventListener("scroll", handleScroll);
2008
- };
2009
- }, [tableContainerRef, updateTableHeight]);
2010
- return maxHeight;
2011
- }
2012
- //#endregion
2013
- //#region src/rwa/components/table-base.tsx
2014
- /**
2015
- * Base table component
2016
- *
2017
- * @type TItem - Table item type, any record with an "id" field and any string keys
2018
- * @type TableColumn - Specifies how to render a column. Must have a `key` which is a key of TItem, and a `label` which is the column header
2019
- * @param tableData - Array of data to display, data must satisfy TItem
2020
- * @param columns - Array of columns to display, column must satisfy TableColumn. The columns will be displayed in the order they are provided. Use the `useColumnPriority` hook to handle dropping columns for smaller screens.
2021
- * @param children - Content to render above the table rows
2022
- * @param footer - Content to render below the table rows
2023
- * @param renderRow - Function to render a row, must return a React element
2024
- * @param onClickSort - Function to handle sorting, called with key and direction
2025
- * @param hasExpandedRow - Whether the table has an expanded row
2026
- * @param specialFirstRow - Function to render a special first row (like the cash asset for instance), must return a React element
2027
- */
2028
- function TableBase(props) {
2029
- const { children, ref, tableData, columns, footer, renderRow, onClickSort, specialFirstRow, specialLastRow, maxHeight, headerRef, hasSelectedItem } = props;
2030
- const [sortDirection, setSortDirection] = useState(null);
2031
- const [sortKey, setSortKey] = useState(null);
2032
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
2033
- className: twJoin("relative rounded-lg border border-gray-300 bg-white", hasSelectedItem ? "overflow-hidden" : "overflow-scroll"),
2034
- ref,
2035
- style: { maxHeight },
2036
- children: /* @__PURE__ */ jsxs("table", {
2037
- className: "w-full",
2038
- children: [/* @__PURE__ */ jsx("thead", {
2039
- className: "sticky top-0 isolate select-none text-nowrap border-b border-gray-300 bg-gray-100",
2040
- ref: headerRef,
2041
- children: /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx("th", {
2042
- className: twMerge("group border-l border-gray-300 py-3 pl-3 text-start text-xs font-medium text-gray-600 first:border-l-0", column.allowSorting && "cursor-pointer hover:text-gray-900"),
2043
- onClick: () => {
2044
- if (!column.allowSorting) return;
2045
- let sortDir = "asc";
2046
- if (sortKey === column.key && sortDirection === "asc") sortDir = "desc";
2047
- setSortDirection(sortDir);
2048
- setSortKey(column.key);
2049
- onClickSort(column.key, sortDir);
2050
- },
2051
- children: /* @__PURE__ */ jsxs("div", {
2052
- className: twMerge("group flex items-center", column.isNumberColumn && "justify-end"),
2053
- children: [column.label, column.allowSorting ? /* @__PURE__ */ jsx(Icon, {
2054
- className: twMerge("invisible ml-1 rotate-90", sortKey === column.key && "group-hover:visible", sortDirection === "asc" && "rotate-[270deg]"),
2055
- name: "ArrowFilledRight",
2056
- size: 6
2057
- }) : null]
2058
- })
2059
- }, column.key)) })
2060
- }), /* @__PURE__ */ jsxs("tbody", { children: [
2061
- children,
2062
- specialFirstRow?.(columns),
2063
- tableData?.map((item, index) => renderRow(item, columns, index)),
2064
- specialLastRow?.(columns)
2065
- ] })]
2066
- })
2067
- }), footer] });
2068
- }
2069
- //#endregion
2070
- //#region src/rwa/components/table.tsx
2071
- function Table(props) {
2072
- const { tableName, tableData, columnCountByTableWidth = defaultColumnCountByTableWidth, sortHandler, specialFirstRow, specialLastRow } = props;
2073
- const columns = columnsByTableName[tableName];
2074
- const { operation, selectedTableItem, isAllowedToCreateDocuments, createItem } = useEditorContext();
2075
- const tableContainerRef = useRef(null);
2076
- const rowRefs = useRef([]);
2077
- const headerRef = useRef(null);
2078
- const columnsToShow = useColumnPriority({
2079
- columns,
2080
- columnCountByTableWidth,
2081
- tableContainerRef
2082
- });
2083
- const maxHeight = useTableHeight({
2084
- tableContainerRef,
2085
- rowRefs,
2086
- headerRef,
2087
- selectedItemNumber: selectedTableItem?.itemNumber,
2088
- hasSpecialLastRow: !!specialLastRow
2089
- });
2090
- const tableLabel = tableLabels[tableName];
2091
- const onCreateItemClick = useCallback(() => {
2092
- createItem(tableName);
2093
- }, [createItem, tableName]);
2094
- const renderRow = useCallback((tableItem, columns, index) => {
2095
- const isSelected = selectedTableItem?.id === tableItem.id;
2096
- return /* @__PURE__ */ jsx(RWATableRow, {
2097
- ref: (el) => rowRefs.current[index] = el,
2098
- children: columns.map((column) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
2099
- column.key === "itemNumber" && /* @__PURE__ */ jsx(ItemNumberCell, { itemNumber: tableItem.itemNumber }),
2100
- column.key !== "itemNumber" && column.key !== "moreDetails" && /* @__PURE__ */ jsx(RWATableCell, {
2101
- className: column.isNumberColumn ? "text-right" : "",
2102
- children: handleTableDatum(tableItem[column.key], column.decimalScale, column.displayTime)
2103
- }, column.key),
2104
- column.key === "moreDetails" && /* @__PURE__ */ jsx(MoreDetailsCell, {
2105
- isSelected,
2106
- tableItem,
2107
- tableName
2108
- })
2109
- ] }, column.key))
2110
- }, tableItem.id);
2111
- }, [selectedTableItem?.id, tableName]);
2112
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(TableBase, {
2113
- columns: columnsToShow,
2114
- hasSelectedItem: !!selectedTableItem,
2115
- headerRef,
2116
- maxHeight,
2117
- onClickSort: sortHandler,
2118
- ref: tableContainerRef,
2119
- renderRow,
2120
- specialFirstRow,
2121
- specialLastRow,
2122
- tableData
2123
- }), isAllowedToCreateDocuments && !operation ? /* @__PURE__ */ jsxs("button", {
2124
- className: "mt-4 flex h-11 w-full items-center justify-center gap-x-2 rounded-lg border border-gray-300 bg-white text-sm font-semibold text-gray-900",
2125
- onClick: onCreateItemClick,
2126
- children: [/* @__PURE__ */ jsxs("span", { children: ["Create ", tableLabel] }), /* @__PURE__ */ jsx(Icon, {
2127
- name: "Plus",
2128
- size: 14
2129
- })]
2130
- }) : null] });
2131
- }
2132
- //#endregion
2133
- //#region src/rwa/components/table-with-form.tsx
2134
- function TableWithForm(props) {
2135
- const { tableName, specialFirstRow, specialLastRow } = props;
2136
- const { getIsFormOpen } = useEditorContext();
2137
- const showForm = getIsFormOpen(tableName);
2138
- const { tableData, sortHandler } = useTableData(tableName);
2139
- const shouldPaginate = tableData.length > 20;
2140
- const { pageItems, pages, goToPage, goToNextPage, goToPreviousPage, goToFirstPage, goToLastPage, hiddenNextPages, isNextPageAvailable, isPreviousPageAvailable } = usePagination(tableData);
2141
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2142
- /* @__PURE__ */ jsx("div", {
2143
- className: "mb-2 flex w-full justify-end",
2144
- children: shouldPaginate ? /* @__PURE__ */ jsx(Pagination, {
2145
- goToFirstPage,
2146
- goToLastPage,
2147
- goToNextPage,
2148
- goToPage,
2149
- goToPreviousPage,
2150
- hiddenNextPages,
2151
- isNextPageAvailable,
2152
- isPreviousPageAvailable,
2153
- nextPageLabel: "Next",
2154
- pages,
2155
- previousPageLabel: "Previous"
2156
- }) : null
2157
- }),
2158
- /* @__PURE__ */ jsx(Table, {
2159
- sortHandler,
2160
- specialFirstRow,
2161
- specialLastRow,
2162
- tableData: pageItems,
2163
- tableName
2164
- }),
2165
- showForm ? /* @__PURE__ */ jsx("div", {
2166
- className: "mt-4 rounded-md bg-white",
2167
- children: /* @__PURE__ */ jsx(ItemDetails, { tableName })
2168
- }) : null
2169
- ] });
2170
- }
2171
- //#endregion
2172
- //#region src/rwa/components/accounts-table.tsx
2173
- function AccountsTable() {
2174
- const { accounts, principalLenderAccountId } = useEditorContext();
2175
- const principalLenderAccount = accounts.find((account) => account.id === principalLenderAccountId);
2176
- const renderPrincipalLenderRow = useCallback((c) => /* @__PURE__ */ jsx(RWATableRow, { children: c.map((column) => /* @__PURE__ */ jsx(Fragment$1, { children: column.key === "label" ? /* @__PURE__ */ jsxs(RWATableCell, { children: [principalLenderAccount?.label, /* @__PURE__ */ jsxs("span", {
2177
- className: "ml-2 inline-flex items-center gap-1 rounded bg-green-100 px-1 font-extralight",
2178
- children: ["Lender ", /* @__PURE__ */ jsx(Icon, {
2179
- name: "CheckCircle",
2180
- size: 14
2181
- })]
2182
- })] }) : /* @__PURE__ */ jsx(RWATableCell, {}) }, column.key)) }), [principalLenderAccount?.label]);
2183
- return /* @__PURE__ */ jsx(TableWithForm, {
2184
- specialFirstRow: principalLenderAccount?.label ? renderPrincipalLenderRow : void 0,
2185
- tableName: tableNames.ACCOUNT
2186
- });
2187
- }
2188
- //#endregion
2189
- //#region src/rwa/components/assets-table.tsx
2190
- function AssetsTable() {
2191
- const tableName = tableNames.ASSET;
2192
- const { selectedTableItem, fixedIncomes, cashAsset } = useEditorContext();
2193
- const cashAssetFormattedAsTableItem = useMemo(() => ({
2194
- id: "special-first-row",
2195
- name: "Cash $USD",
2196
- fixedIncomeTypeId: "--",
2197
- spvId: "--",
2198
- maturity: "--",
2199
- ISIN: "--",
2200
- CUSIP: "--",
2201
- coupon: null,
2202
- notional: cashAsset.balance ?? 0,
2203
- purchaseDate: "--",
2204
- purchasePrice: "--",
2205
- purchaseProceeds: "--",
2206
- salesProceeds: "--",
2207
- totalDiscount: "--",
2208
- realizedSurplus: "--",
2209
- currentValue: "--"
2210
- }), [cashAsset.balance]);
2211
- const totalPurchaseProceeds = sumTotalForProperty(fixedIncomes, "purchaseProceeds");
2212
- const totalSalesProceeds = sumTotalForProperty(fixedIncomes, "salesProceeds");
2213
- const totalTotalDiscount = sumTotalForProperty(fixedIncomes, "totalDiscount");
2214
- const totalRealizedSurplus = sumTotalForProperty(fixedIncomes, "realizedSurplus");
2215
- return /* @__PURE__ */ jsx(TableWithForm, {
2216
- specialFirstRow: useCallback((c) => /* @__PURE__ */ jsx(RWATableRow, { children: c.map((column) => /* @__PURE__ */ jsxs(Fragment, { children: [
2217
- column.key === "name" && /* @__PURE__ */ jsx(RWATableCell, { children: "Cash $USD" }),
2218
- column.key === "notional" && /* @__PURE__ */ jsx(RWATableCell, {
2219
- className: "text-right",
2220
- children: handleTableDatum(cashAssetFormattedAsTableItem[column.key])
2221
- }, column.key),
2222
- column.key !== "name" && column.key !== "notional" && /* @__PURE__ */ jsx(RWATableCell, {})
2223
- ] }, column.key)) }), [cashAssetFormattedAsTableItem]),
2224
- specialLastRow: useCallback((c) => /* @__PURE__ */ jsx(RWATableRow, {
2225
- className: "sticky bottom-0",
2226
- children: c.map((column) => /* @__PURE__ */ jsxs(Fragment, { children: [
2227
- column.key === "name" && /* @__PURE__ */ jsx(RWATableCell, { children: "Totals" }),
2228
- column.key === "purchaseProceeds" && /* @__PURE__ */ jsx(RWATableCell, {
2229
- className: "text-right",
2230
- children: handleTableDatum(totalPurchaseProceeds)
2231
- }, column.key),
2232
- column.key === "salesProceeds" && /* @__PURE__ */ jsx(RWATableCell, {
2233
- className: "text-right",
2234
- children: handleTableDatum(totalSalesProceeds)
2235
- }, column.key),
2236
- column.key === "totalDiscount" && /* @__PURE__ */ jsx(RWATableCell, {
2237
- className: "text-right",
2238
- children: handleTableDatum(totalTotalDiscount)
2239
- }, column.key),
2240
- column.key === "realizedSurplus" && /* @__PURE__ */ jsx(RWATableCell, {
2241
- className: "text-right",
2242
- children: handleTableDatum(totalRealizedSurplus)
2243
- }, column.key),
2244
- column.key !== "name" && column.key !== "purchaseProceeds" && column.key !== "salesProceeds" && column.key !== "totalDiscount" && column.key !== "realizedSurplus" && /* @__PURE__ */ jsx(RWATableCell, {})
2245
- ] }, column.key))
2246
- }), [
2247
- selectedTableItem,
2248
- totalPurchaseProceeds,
2249
- totalRealizedSurplus,
2250
- totalSalesProceeds,
2251
- totalTotalDiscount
2252
- ]),
2253
- tableName
2254
- });
2255
- }
2256
- //#endregion
2257
- //#region src/rwa/components/modal-form-inputs.tsx
2258
- function ModalFormInputs(props) {
2259
- const { inputs } = props;
2260
- return /* @__PURE__ */ jsx("div", {
2261
- className: "bg-white text-xs font-medium",
2262
- children: inputs.map(({ label, Input }, index) => /* @__PURE__ */ jsxs("div", {
2263
- className: "mb-4 mt-2 grid gap-1",
2264
- children: [/* @__PURE__ */ jsx("label", {
2265
- className: "text-base",
2266
- children: label
2267
- }), /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Input, {}) }, index)]
2268
- }, label))
2269
- });
2270
- }
2271
- //#endregion
2272
- //#region src/rwa/components/create-item-modal.tsx
2273
- const RWACreateItemModal = /* @__PURE__ */ memo(function RWACreateItemModal(props) {
2274
- const { tableName, open, onOpenChange } = props;
2275
- const { reset, submit, formInputs: { inputs, additionalInputs } } = useTableForm({
2276
- operation: "create",
2277
- tableName
2278
- });
2279
- const tableLabel = tableLabels[tableName];
2280
- const handleCancel = useCallback(() => {
2281
- reset();
2282
- onOpenChange(false);
2283
- }, [onOpenChange, reset]);
2284
- const handleSubmit = useCallback(async () => {
2285
- try {
2286
- await submit();
2287
- onOpenChange(false);
2288
- } catch (error) {
2289
- console.error(error);
2290
- }
2291
- }, [onOpenChange, submit]);
2292
- const buttonStyles = "min-h-[48px] min-w-[142px] text-base font-semibold py-3 px-6 rounded-xl outline-none active:opacity-75 hover:scale-105 transform transition-all";
2293
- return /* @__PURE__ */ jsx(Modal, {
2294
- contentProps: { className: "rounded-3xl" },
2295
- onOpenChange,
2296
- open,
2297
- overlayProps: { className: "top-10" },
2298
- children: /* @__PURE__ */ jsxs("div", {
2299
- className: "w-[400px] p-6 text-slate-300",
2300
- children: [
2301
- /* @__PURE__ */ jsxs("div", {
2302
- className: "mb-6 flex justify-between",
2303
- children: [/* @__PURE__ */ jsxs("h1", {
2304
- className: "text-xl font-bold",
2305
- children: ["Create ", tableLabel]
2306
- }), /* @__PURE__ */ jsx("button", {
2307
- className: "flex size-8 items-center justify-center rounded-md bg-gray-100 text-gray-500 outline-none hover:text-gray-900",
2308
- onClick: handleCancel,
2309
- tabIndex: -1,
2310
- children: /* @__PURE__ */ jsx(Icon, {
2311
- name: "XmarkLight",
2312
- size: 24
2313
- })
2314
- })]
2315
- }),
2316
- /* @__PURE__ */ jsx(ModalFormInputs, { inputs }),
2317
- additionalInputs,
2318
- /* @__PURE__ */ jsxs("div", {
2319
- className: "mt-8 flex justify-between gap-3",
2320
- children: [/* @__PURE__ */ jsx("button", {
2321
- className: twMerge(buttonStyles, "flex-1 bg-slate-50 text-slate-800"),
2322
- onClick: handleCancel,
2323
- children: "Cancel"
2324
- }), /* @__PURE__ */ jsx("button", {
2325
- className: twMerge(buttonStyles, "flex-1 bg-gray-800 text-gray-50"),
2326
- onClick: handleSubmit,
2327
- children: "Save"
2328
- })]
2329
- })
2330
- ]
2331
- })
2332
- });
2333
- });
2334
- //#endregion
2335
- //#region src/rwa/components/delete-item-modal.tsx
2336
- const RWADeleteItemModal = /* @__PURE__ */ memo(function RWADeleteItemModal(props) {
2337
- const { tableName, dependentItemProps, onOpenChange, open } = props;
2338
- const tableLabel = tableLabels[tableName].toLowerCase();
2339
- const handleCancel = useCallback(() => {
2340
- onOpenChange?.(false);
2341
- }, [onOpenChange]);
2342
- return /* @__PURE__ */ jsx(Modal, {
2343
- contentProps: { className: "rounded-3xl" },
2344
- onOpenChange,
2345
- open,
2346
- overlayProps: { className: "top-10" },
2347
- children: /* @__PURE__ */ jsxs("div", {
2348
- className: "w-[400px] p-6 text-slate-300",
2349
- children: [
2350
- /* @__PURE__ */ jsxs("div", {
2351
- className: "border-b border-slate-50 pb-2 text-2xl font-bold text-gray-800",
2352
- children: ["Cannot delete ", tableName]
2353
- }),
2354
- /* @__PURE__ */ jsxs("div", {
2355
- className: "my-6 flex gap-2 rounded-md bg-orange-100 p-4 text-orange-800",
2356
- children: [/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Icon, {
2357
- className: "mt-1 text-orange-800",
2358
- name: "Error"
2359
- }) }), /* @__PURE__ */ jsxs("div", { children: [
2360
- "Warning! Cannot delete this ",
2361
- tableLabel,
2362
- " because there are items that depend on it. Please change or delete those first."
2363
- ] })]
2364
- }),
2365
- /* @__PURE__ */ jsx("div", {
2366
- className: "my-6 rounded-md bg-slate-50 p-4 text-slate-200",
2367
- children: dependentItemProps.map(({ dependentTableName, dependentItems }) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
2368
- className: "mb-0.5 font-semibold",
2369
- children: `${tableLabels[dependentTableName]}s: `
2370
- }, 1), dependentItems.map(({ id, label }) => /* @__PURE__ */ jsx("div", { children: label }, id))] }, dependentTableName))
2371
- }),
2372
- /* @__PURE__ */ jsx("div", {
2373
- className: "mt-8 flex justify-between gap-3",
2374
- children: /* @__PURE__ */ jsx("button", {
2375
- className: "min-h-12 min-w-36 flex-1 rounded-xl bg-gray-800 px-6 py-3 text-base font-semibold text-gray-50 outline-none transition-all hover:scale-105 active:opacity-75",
2376
- onClick: handleCancel,
2377
- children: "Back"
2378
- })
2379
- })
2380
- ]
2381
- })
2382
- });
2383
- });
2384
- //#endregion
2385
- //#region src/rwa/components/modal-components.ts
2386
- const modals = {
2387
- createItem: RWACreateItemModal,
2388
- deleteItem: RWADeleteItemModal
2389
- };
2390
- //#endregion
2391
- //#region src/rwa/components/modal-manager.tsx
2392
- const ModalManager = (props) => {
2393
- const { children } = props;
2394
- const [modalProps, setModalProps] = useState();
2395
- const [modalType, setModalType] = useState();
2396
- const [open, setOpen] = useState(false);
2397
- const showModal = useCallback((modalType, props) => {
2398
- setOpen(true);
2399
- setModalProps(props);
2400
- setModalType(modalType);
2401
- }, []);
2402
- const closeModal = useCallback(() => {
2403
- setOpen(false);
2404
- }, []);
2405
- const ModalComponent = modalType ? modals[modalType] : null;
2406
- const value = useMemo(() => ({
2407
- showModal,
2408
- closeModal
2409
- }), [closeModal, showModal]);
2410
- return /* @__PURE__ */ jsxs(ModalContext.Provider, {
2411
- value,
2412
- children: [children, ModalComponent ? /* @__PURE__ */ jsx(ModalComponent, {
2413
- ...modalProps,
2414
- onOpenChange: setOpen,
2415
- open
2416
- }) : null]
2417
- });
2418
- };
2419
- //#endregion
2420
- //#region src/rwa/components/other-tab.tsx
2421
- function OtherTab() {
2422
- return /* @__PURE__ */ jsxs("div", {
2423
- className: "grid grid-rows-4 gap-4",
2424
- children: [
2425
- /* @__PURE__ */ jsxs("div", { children: [
2426
- /* @__PURE__ */ jsx("h2", {
2427
- className: "mb-2 text-lg font-bold",
2428
- children: "Accounts"
2429
- }),
2430
- /* @__PURE__ */ jsx("p", {
2431
- className: "mb-4 text-xs text-gray-600",
2432
- children: "Add and manage accounts that can be associated with transactions and fees."
2433
- }),
2434
- /* @__PURE__ */ jsx(AccountsTable, {})
2435
- ] }),
2436
- /* @__PURE__ */ jsxs("div", { children: [
2437
- /* @__PURE__ */ jsx("h2", {
2438
- className: "mb-2 text-lg font-bold",
2439
- children: "Fixed Income Types"
2440
- }),
2441
- /* @__PURE__ */ jsx("p", {
2442
- className: "mb-4 text-xs text-gray-600",
2443
- children: "Add and manage fixed income asset types."
2444
- }),
2445
- /* @__PURE__ */ jsx(TableWithForm, { tableName: tableNames.FIXED_INCOME_TYPE })
2446
- ] }),
2447
- /* @__PURE__ */ jsxs("div", { children: [
2448
- /* @__PURE__ */ jsx("h2", {
2449
- className: "mb-2 text-lg font-bold",
2450
- children: "SPVs"
2451
- }),
2452
- /* @__PURE__ */ jsx("p", {
2453
- className: "mb-4 text-xs text-gray-600",
2454
- children: "Add and manage special purpose vehicles (SPVs)."
2455
- }),
2456
- /* @__PURE__ */ jsx(TableWithForm, { tableName: tableNames.SPV })
2457
- ] }),
2458
- /* @__PURE__ */ jsxs("div", { children: [
2459
- /* @__PURE__ */ jsx("h2", {
2460
- className: "mb-2 text-lg font-bold",
2461
- children: "Service Provider Fee Types"
2462
- }),
2463
- /* @__PURE__ */ jsx("p", {
2464
- className: "mb-4 text-xs text-gray-600",
2465
- children: "Add and manage service providers and their associated fee types."
2466
- }),
2467
- /* @__PURE__ */ jsx(TableWithForm, { tableName: tableNames.SERVICE_PROVIDER_FEE_TYPE })
2468
- ] })
2469
- ]
2470
- });
2471
- }
2472
- //#endregion
2473
- //#region src/rwa/components/rwa-tab-content.tsx
2474
- function RwaTabContent(props) {
2475
- const { label, description, children } = props;
2476
- return /* @__PURE__ */ jsxs("div", { children: [
2477
- /* @__PURE__ */ jsx("h1", {
2478
- className: "mb-2 text-lg font-bold",
2479
- children: label
2480
- }),
2481
- /* @__PURE__ */ jsx("p", {
2482
- className: "mb-4 text-xs text-gray-600",
2483
- children: description
2484
- }),
2485
- children
2486
- ] });
2487
- }
2488
- //#endregion
2489
- //#region src/rwa/components/portfolio-tab.tsx
2490
- function PortfolioTab() {
2491
- return /* @__PURE__ */ jsx(RwaTabContent, {
2492
- description: "Details on the distribution of assets among different financial institutions or investment vehicles.",
2493
- label: "Portfolio",
2494
- children: /* @__PURE__ */ jsx(AssetsTable, {})
2495
- });
2496
- }
2497
- //#endregion
2498
- //#region src/rwa/components/group-transactions-table.tsx
2499
- function GroupTransactionsTable() {
2500
- const tableName = tableNames.TRANSACTION;
2501
- const { getIsFormOpen, fixedIncomes } = useEditorContext();
2502
- const showForm = getIsFormOpen(tableName);
2503
- const { tableData, sortHandler } = useTableData(tableName);
2504
- const [filteredTableData, setFilteredTableData] = useState(tableData);
2505
- const [filterAssetId, setFilterAssetId] = useState();
2506
- const [filterTypes, setFilterTypes] = useState([]);
2507
- const shouldPaginate = filteredTableData.length > 20;
2508
- useEffect(() => {
2509
- if (!filterAssetId && !filterTypes.length) {
2510
- setFilteredTableData(tableData);
2511
- return;
2512
- }
2513
- setFilteredTableData(tableData.filter((transaction) => {
2514
- if (filterAssetId && filterTypes.length) return transaction.fixedIncomeTransaction?.assetId === filterAssetId && filterTypes.includes(transaction.type);
2515
- if (filterAssetId) return transaction.fixedIncomeTransaction?.assetId === filterAssetId;
2516
- if (filterTypes.length) return filterTypes.includes(transaction.type);
2517
- }));
2518
- }, [
2519
- filterAssetId,
2520
- filterTypes,
2521
- tableData
2522
- ]);
2523
- const filterByAssetOptions = useMemo(() => fixedIncomes.map((asset) => ({
2524
- label: makeFixedIncomeOptionLabel(asset),
2525
- value: asset.id
2526
- })), [fixedIncomes]);
2527
- const filterByTypeOptions = useMemo(() => allGroupTransactionTypes.map((type) => ({
2528
- label: groupTransactionTypeLabels[type],
2529
- value: type
2530
- })), []);
2531
- const { pageItems, pages, goToPage, goToNextPage, goToPreviousPage, goToFirstPage, goToLastPage, hiddenNextPages, isNextPageAvailable, isPreviousPageAvailable } = usePagination(filteredTableData);
2532
- const handleFilterByAssetChange = useCallback((update) => {
2533
- if (!update || !(typeof update === "object") || !("value" in update)) {
2534
- setFilterAssetId(void 0);
2535
- return;
2536
- }
2537
- const { value: assetId } = update;
2538
- setFilterAssetId(assetId);
2539
- }, []);
2540
- const handleFilterByTypeChange = useCallback((update) => {
2541
- if (!update || !Array.isArray(update)) {
2542
- setFilterTypes([]);
2543
- return;
2544
- }
2545
- setFilterTypes(update.map(({ value }) => value));
2546
- }, []);
2547
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2548
- /* @__PURE__ */ jsxs("div", {
2549
- className: "mb-2 flex gap-2",
2550
- children: [
2551
- /* @__PURE__ */ jsx("div", {
2552
- className: "min-w-72 max-w-96",
2553
- children: /* @__PURE__ */ jsx(Combobox, {
2554
- isClearable: true,
2555
- onChange: handleFilterByAssetChange,
2556
- options: filterByAssetOptions,
2557
- placeholder: "Filter by Asset"
2558
- })
2559
- }),
2560
- /* @__PURE__ */ jsx("div", {
2561
- className: "min-w-72 max-w-96",
2562
- children: /* @__PURE__ */ jsx(Combobox, {
2563
- isClearable: true,
2564
- isMulti: true,
2565
- onChange: handleFilterByTypeChange,
2566
- options: filterByTypeOptions,
2567
- placeholder: "Filter by Type"
2568
- })
2569
- }),
2570
- /* @__PURE__ */ jsx("div", {
2571
- className: "flex w-full justify-end",
2572
- children: shouldPaginate ? /* @__PURE__ */ jsx(Pagination, {
2573
- goToFirstPage,
2574
- goToLastPage,
2575
- goToNextPage,
2576
- goToPage,
2577
- goToPreviousPage,
2578
- hiddenNextPages,
2579
- isNextPageAvailable,
2580
- isPreviousPageAvailable,
2581
- nextPageLabel: "Next",
2582
- pages,
2583
- previousPageLabel: "Previous"
2584
- }) : null
2585
- })
2586
- ]
2587
- }),
2588
- /* @__PURE__ */ jsx(Table, {
2589
- sortHandler,
2590
- tableData: pageItems,
2591
- tableName
2592
- }),
2593
- showForm ? /* @__PURE__ */ jsx("div", {
2594
- className: "mt-4 rounded-md bg-white",
2595
- children: /* @__PURE__ */ jsx(ItemDetails, { tableName })
2596
- }) : null
2597
- ] });
2598
- }
2599
- //#endregion
2600
- //#region src/rwa/components/transactions-tab.tsx
2601
- function TransactionsTab() {
2602
- return /* @__PURE__ */ jsx(RwaTabContent, {
2603
- description: "Details on the distribution of assets among different financial institutions or investment vehicles.",
2604
- label: "Transactions",
2605
- children: /* @__PURE__ */ jsx(GroupTransactionsTable, {})
2606
- });
2607
- }
2608
- //#endregion
2609
- //#region src/rwa/components/tabs.tsx
2610
- function RWATabs() {
2611
- const tabs = [
2612
- "Portfolio",
2613
- "Transactions",
2614
- "Other"
2615
- ];
2616
- const { onSwitchboardLinkClick, onExport, onClose, onShowRevisionHistory, clearSelected } = useEditorContext();
2617
- return /* @__PURE__ */ jsxs(Root, {
2618
- defaultValue: "Portfolio",
2619
- onValueChange: useCallback(() => {
2620
- clearSelected();
2621
- }, [clearSelected]),
2622
- children: [/* @__PURE__ */ jsxs("div", {
2623
- className: "flex justify-between",
2624
- children: [/* @__PURE__ */ jsx(List, {
2625
- className: "flex gap-x-2 rounded-xl bg-slate-50 p-1 text-sm font-semibold text-gray-600 outline-none",
2626
- children: tabs.map((tab) => /* @__PURE__ */ jsx(Trigger, {
2627
- className: "data-[state='active']:tab-shadow data-disabled:cursor-not-allowed data-disabled:text-gray-400 h-7 w-32 rounded-lg transition duration-300 data-[state='active']:bg-gray-50 data-[state='active']:text-gray-900",
2628
- value: tab,
2629
- children: tab
2630
- }, tab))
2631
- }), /* @__PURE__ */ jsx(EditorActionButtons, {
2632
- onClose,
2633
- onExport,
2634
- onShowRevisionHistory,
2635
- onSwitchboardLinkClick
2636
- })]
2637
- }), /* @__PURE__ */ jsxs("div", {
2638
- className: "mt-3 rounded-md bg-slate-50 p-8",
2639
- children: [
2640
- /* @__PURE__ */ jsx(Content, {
2641
- value: "Portfolio",
2642
- children: /* @__PURE__ */ jsx(PortfolioTab, {})
2643
- }),
2644
- /* @__PURE__ */ jsx(Content, {
2645
- value: "Transactions",
2646
- children: /* @__PURE__ */ jsx(TransactionsTab, {})
2647
- }),
2648
- /* @__PURE__ */ jsx(Content, {
2649
- value: "Other",
2650
- children: /* @__PURE__ */ jsx(OtherTab, {})
2651
- })
2652
- ]
2653
- })]
2654
- });
2655
- }
2656
- //#endregion
2657
- //#region src/rwa/components/editor.tsx
2658
- function RWAEditor() {
2659
- return /* @__PURE__ */ jsx(ModalManager, { children: /* @__PURE__ */ jsx(RWATabs, {}) });
2660
- }
2661
- //#endregion
2662
- //#region src/rwa/components/form-row.tsx
2663
- const RWAFormRow = ({ label, value, ...divProps }) => /* @__PURE__ */ jsxs("div", {
2664
- ...mergeClassNameProps(divProps, "flex items-center px-6 text-xs"),
2665
- children: [/* @__PURE__ */ jsx("div", {
2666
- className: "text-gray-600",
2667
- children: label
2668
- }), /* @__PURE__ */ jsx("div", {
2669
- className: "text-gray-900",
2670
- children: value ? value : "--"
2671
- })]
2672
- });
2673
- //#endregion
2674
- //#region src/rwa/components/header-label.tsx
2675
- const RWATableHeaderLabel = (props) => {
2676
- const { label, ...divProps } = props;
2677
- return /* @__PURE__ */ jsx("th", {
2678
- scope: "col",
2679
- ...divProps,
2680
- children: label
2681
- });
2682
- };
2683
- //#endregion
2684
- export { ASSET_PURCHASE, ASSET_SALE, AccountsTable, AssetsTable, CashBalanceChange, EntryTimeLabel, FEES_INCOME, FEES_PAYMENT, FeeTransactionsTable, FormInputs, FormattedNumber, GroupTransactionsTable, INTEREST_INCOME, INTEREST_PAYMENT, ItemDetails, ItemNumberCell, ModalContext, ModalFormInputs, ModalManager, MoreDetailsCell, OtherTab, PRINCIPAL_DRAW, PRINCIPAL_RETURN, PortfolioTab, RWAButton, RWACreateItemModal, RWADeleteItemModal, RWAEditor, RWAEditorContextProvider, RWAFormRow, RWANumberInput, RWATableCell, RWATableHeaderLabel, RWATableRow, RWATableSelect, RWATableTextInput, RWATabs, RwaTabContent, Table, TableBase, TableWithForm, TransactionReference, TransactionsTab, UnitPrice, allGroupTransactionTypes, assetGroupTransactions, assetTransactionSignByTransactionType, calculateCashBalanceChange, calculateCurrentValue, calculateSumQuantity, calculateUnitPrice, cashTransactionSignByTransactionType, columnsByTableName, defaultColumnCountByTableWidth, deleteEditorActionInputsByTableName, editorStateKeysByTableName, feesTransactions, formatDateForDisplay, getActionOperationType, getCashAsset, getColumnCount, getFixedIncomeAssets, getStateKeyForTableName, getTableNameFor, getTimeZone, groupTransactionTypeLabels, handleDateInTable, handleTableDatum, interestTransactions, isAssetGroupTransactionType, isCashAsset, isFixedIncomeAsset, isISODate, isoDateStringToDateInput, makeDependentAssetsList, makeDependentServiceProviderFeeTypesList, makeDependentTransactionsList, makeFixedIncomeOptionLabel, makeTableData, math, modals, principalGroupTransactions, sumTotalForProperty, tableDataMakersByTableName, tableLabels, tableNames, useColumnPriority, useDefaultFormValues, useDependentItemProps, useEditorContext, useFormInputs, useModal, useSortTableItems, useSubmit, useTableData, useTableForm, useTableHeight };
2685
-
2686
- //# sourceMappingURL=index.js.map