@loafmarkets/ui 0.1.412 → 0.1.413
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +104 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +104 -38
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -15097,6 +15097,9 @@ var STATUS_COLOR2 = {
|
|
|
15097
15097
|
CLOSED: "#848e9c",
|
|
15098
15098
|
CANCELLED: "#f6465d"
|
|
15099
15099
|
};
|
|
15100
|
+
var STUCK_SETTLING_MS = 7e3;
|
|
15101
|
+
var SETTLING_MESSAGE = "Trade settling on-chain";
|
|
15102
|
+
var STUCK_SETTLING_MESSAGE = "Attention: Trade taking longer than usual to settle on chain. Please wait up to 10 seconds before trading. This is reflected in your locked balance.";
|
|
15100
15103
|
var settlingSpin = keyframes`
|
|
15101
15104
|
to { transform: rotate(360deg); }
|
|
15102
15105
|
`;
|
|
@@ -15110,41 +15113,55 @@ var SettlingSpinner = styled10.span`
|
|
|
15110
15113
|
animation: ${settlingSpin} 0.7s linear infinite;
|
|
15111
15114
|
flex-shrink: 0;
|
|
15112
15115
|
`;
|
|
15116
|
+
var StuckSettlingGlyph = styled10.span`
|
|
15117
|
+
display: inline-block;
|
|
15118
|
+
font-size: 11px;
|
|
15119
|
+
line-height: 1;
|
|
15120
|
+
flex-shrink: 0;
|
|
15121
|
+
`;
|
|
15113
15122
|
var SettlingTip = styled10.span`
|
|
15114
15123
|
position: relative;
|
|
15115
15124
|
display: inline-flex;
|
|
15116
15125
|
align-items: center;
|
|
15117
15126
|
cursor: help;
|
|
15118
|
-
|
|
15119
|
-
|
|
15120
|
-
|
|
15121
|
-
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
|
|
15125
|
-
|
|
15126
|
-
|
|
15127
|
-
|
|
15128
|
-
|
|
15129
|
-
|
|
15130
|
-
|
|
15131
|
-
|
|
15132
|
-
|
|
15133
|
-
|
|
15134
|
-
|
|
15135
|
-
|
|
15136
|
-
|
|
15137
|
-
|
|
15138
|
-
|
|
15139
|
-
|
|
15140
|
-
|
|
15141
|
-
|
|
15142
|
-
|
|
15127
|
+
`;
|
|
15128
|
+
var SettlingTipBubble = styled10.span`
|
|
15129
|
+
position: absolute;
|
|
15130
|
+
bottom: calc(100% + 8px);
|
|
15131
|
+
/* Stuck copy is a paragraph, so it anchors to the icon's left edge instead of
|
|
15132
|
+
centring — centred it would hang off the left of the row. */
|
|
15133
|
+
left: ${(p) => p.$stuck ? "0" : "50%"};
|
|
15134
|
+
transform: ${(p) => p.$stuck ? "translateX(0)" : "translateX(-50%)"} translateY(3px);
|
|
15135
|
+
width: ${(p) => p.$stuck ? "224px" : "auto"};
|
|
15136
|
+
white-space: ${(p) => p.$stuck ? "normal" : "nowrap"};
|
|
15137
|
+
padding: 6px 8px;
|
|
15138
|
+
background: rgba(20, 22, 28, 0.97);
|
|
15139
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
15140
|
+
border-radius: 6px;
|
|
15141
|
+
color: rgba(255, 255, 255, 0.78);
|
|
15142
|
+
font-size: 0.66rem;
|
|
15143
|
+
font-weight: 400;
|
|
15144
|
+
line-height: 1.35;
|
|
15145
|
+
letter-spacing: normal;
|
|
15146
|
+
text-transform: none;
|
|
15147
|
+
text-align: left;
|
|
15148
|
+
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
|
|
15149
|
+
opacity: 0;
|
|
15150
|
+
visibility: hidden;
|
|
15151
|
+
transition: opacity 0.15s ease, transform 0.15s ease;
|
|
15152
|
+
pointer-events: none;
|
|
15153
|
+
z-index: 2000;
|
|
15154
|
+
|
|
15155
|
+
${SettlingTip}:hover & {
|
|
15143
15156
|
opacity: 1;
|
|
15144
15157
|
visibility: visible;
|
|
15145
|
-
transform: translateX(-50%) translateY(0);
|
|
15158
|
+
transform: ${(p) => p.$stuck ? "translateX(0)" : "translateX(-50%)"} translateY(0);
|
|
15146
15159
|
}
|
|
15147
15160
|
`;
|
|
15161
|
+
var SettlingIndicator = ({ stuck, style }) => /* @__PURE__ */ jsxs(SettlingTip, { role: "img", "aria-label": stuck ? "Settlement delayed" : SETTLING_MESSAGE, style, children: [
|
|
15162
|
+
stuck ? /* @__PURE__ */ jsx(StuckSettlingGlyph, { "aria-hidden": "true", children: "\u26A0\uFE0F" }) : /* @__PURE__ */ jsx(SettlingSpinner, { "aria-hidden": "true" }),
|
|
15163
|
+
/* @__PURE__ */ jsx(SettlingTipBubble, { $stuck: stuck, children: stuck ? STUCK_SETTLING_MESSAGE : SETTLING_MESSAGE })
|
|
15164
|
+
] });
|
|
15148
15165
|
var ACTIVITY_PAGE_SIZE_DEFAULT = 8;
|
|
15149
15166
|
var formatCurrency4 = (value, opts) => {
|
|
15150
15167
|
const min = opts?.minimumFractionDigits ?? 2;
|
|
@@ -15152,14 +15169,21 @@ var formatCurrency4 = (value, opts) => {
|
|
|
15152
15169
|
return `$${value.toLocaleString("en-US", { minimumFractionDigits: min, maximumFractionDigits: max })}`;
|
|
15153
15170
|
};
|
|
15154
15171
|
var formatNumber2 = (value, maximumFractionDigits = 2) => value.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits });
|
|
15172
|
+
var toMillis = (unix) => {
|
|
15173
|
+
if (unix > 1e18) return Math.floor(unix / 1e6);
|
|
15174
|
+
if (unix > 1e14) return Math.floor(unix / 1e3);
|
|
15175
|
+
if (unix > 1e12) return unix;
|
|
15176
|
+
return unix * 1e3;
|
|
15177
|
+
};
|
|
15178
|
+
var SETTLED_TRADE_STATUSES = ["SETTLED", "CONFIRMED", "FILLED", "ALLOCATED"];
|
|
15179
|
+
var FAILED_TRADE_STATUSES = ["SETTLEMENT_FAILED", "REJECTED", "CANCELLED", "CANCELED"];
|
|
15180
|
+
var tradeIsSettling = (status) => {
|
|
15181
|
+
const s = status?.toUpperCase();
|
|
15182
|
+
return !!s && !SETTLED_TRADE_STATUSES.includes(s) && !FAILED_TRADE_STATUSES.includes(s);
|
|
15183
|
+
};
|
|
15155
15184
|
var formatTimestamp = (unix) => {
|
|
15156
15185
|
if (!unix) return "\u2014";
|
|
15157
|
-
|
|
15158
|
-
if (unix > 1e18) sec = Math.floor(unix / 1e9);
|
|
15159
|
-
else if (unix > 1e14) sec = Math.floor(unix / 1e6);
|
|
15160
|
-
else if (unix > 1e12) sec = Math.floor(unix / 1e3);
|
|
15161
|
-
else sec = unix;
|
|
15162
|
-
return new Date(sec * 1e3).toLocaleString("en-AU", {
|
|
15186
|
+
return new Date(toMillis(unix)).toLocaleString("en-AU", {
|
|
15163
15187
|
day: "2-digit",
|
|
15164
15188
|
month: "short",
|
|
15165
15189
|
hour: "2-digit",
|
|
@@ -15223,6 +15247,40 @@ function PortfolioActivityPanel({
|
|
|
15223
15247
|
const [closeAllOpen, setCloseAllOpen] = useState(false);
|
|
15224
15248
|
const [closeAllType, setCloseAllType] = useState("market");
|
|
15225
15249
|
const [closingAll, setClosingAll] = useState(false);
|
|
15250
|
+
const settlingPositionIds = positions.filter((p) => p.settling).map((p) => p.propertyId);
|
|
15251
|
+
const settlingKey = settlingPositionIds.join(",");
|
|
15252
|
+
const settlingTradeStartByProperty = /* @__PURE__ */ new Map();
|
|
15253
|
+
const settlingTradeDeadlines = [];
|
|
15254
|
+
for (const trade of tradeHistory) {
|
|
15255
|
+
if (!tradeIsSettling(trade.status)) continue;
|
|
15256
|
+
const startedAt = toMillis(trade.executedAt);
|
|
15257
|
+
settlingTradeDeadlines.push(startedAt + STUCK_SETTLING_MS);
|
|
15258
|
+
const earliest = settlingTradeStartByProperty.get(trade.propertyId);
|
|
15259
|
+
if (earliest === void 0 || startedAt < earliest) settlingTradeStartByProperty.set(trade.propertyId, startedAt);
|
|
15260
|
+
}
|
|
15261
|
+
const tradeDeadlineKey = settlingTradeDeadlines.join(",");
|
|
15262
|
+
const settlingSinceRef = useRef(/* @__PURE__ */ new Map());
|
|
15263
|
+
const [now, setNow] = useState(() => Date.now());
|
|
15264
|
+
useEffect(() => {
|
|
15265
|
+
const since = settlingSinceRef.current;
|
|
15266
|
+
const seenAt = Date.now();
|
|
15267
|
+
for (const id of settlingPositionIds) if (!since.has(id)) since.set(id, seenAt);
|
|
15268
|
+
for (const id of [...since.keys()]) if (!settlingPositionIds.includes(id)) since.delete(id);
|
|
15269
|
+
setNow(seenAt);
|
|
15270
|
+
}, [settlingKey]);
|
|
15271
|
+
const positionSettlingStart = (propertyId) => settlingTradeStartByProperty.get(propertyId) ?? settlingSinceRef.current.get(propertyId) ?? now;
|
|
15272
|
+
useEffect(() => {
|
|
15273
|
+
const pending = [
|
|
15274
|
+
...settlingPositionIds.map((id) => positionSettlingStart(id) + STUCK_SETTLING_MS),
|
|
15275
|
+
...settlingTradeDeadlines
|
|
15276
|
+
].filter((deadline) => deadline > now);
|
|
15277
|
+
if (pending.length === 0) return;
|
|
15278
|
+
const delay = Math.min(Math.min(...pending) - now + 50, 2147483647);
|
|
15279
|
+
const timer = setTimeout(() => setNow(Date.now()), delay);
|
|
15280
|
+
return () => clearTimeout(timer);
|
|
15281
|
+
}, [settlingKey, tradeDeadlineKey, now]);
|
|
15282
|
+
const isPositionStuck = (pos) => !!pos.settling && now - positionSettlingStart(pos.propertyId) >= STUCK_SETTLING_MS;
|
|
15283
|
+
const isTradeStuck = (trade) => now - toMillis(trade.executedAt) >= STUCK_SETTLING_MS;
|
|
15226
15284
|
const hasPositionActions = !!(onClosePosition || onSharePosition || onCloseAllPositions);
|
|
15227
15285
|
const [posSortKey, setPosSortKey] = useState("asset");
|
|
15228
15286
|
const [posSortAsc, setPosSortAsc] = useState(true);
|
|
@@ -15477,7 +15535,7 @@ function PortfolioActivityPanel({
|
|
|
15477
15535
|
/* @__PURE__ */ jsx(CCellLabel, { children: "Asset" }),
|
|
15478
15536
|
/* @__PURE__ */ jsxs(CAssetName, { children: [
|
|
15479
15537
|
pos.tokenName,
|
|
15480
|
-
pos.settling && /* @__PURE__ */ jsx(
|
|
15538
|
+
pos.settling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: isPositionStuck(pos), style: { marginLeft: 6 } })
|
|
15481
15539
|
] })
|
|
15482
15540
|
] }),
|
|
15483
15541
|
/* @__PURE__ */ jsxs(CUnitsCell, { children: [
|
|
@@ -15569,7 +15627,7 @@ function PortfolioActivityPanel({
|
|
|
15569
15627
|
return /* @__PURE__ */ jsxs(PositionsRow, { $hasClose: hasPositionActions, children: [
|
|
15570
15628
|
/* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
15571
15629
|
/* @__PURE__ */ jsx(HoldingsPropertyLink, { onClick: () => onPositionClick?.(pos.tokenName, pos.isIpoAllocation), children: pos.tokenName }),
|
|
15572
|
-
pos.settling && /* @__PURE__ */ jsx(
|
|
15630
|
+
pos.settling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: isPositionStuck(pos) })
|
|
15573
15631
|
] }) }),
|
|
15574
15632
|
/* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: [
|
|
15575
15633
|
formatNumber2(pos.totalQuantity),
|
|
@@ -15950,7 +16008,8 @@ function PortfolioActivityPanel({
|
|
|
15950
16008
|
const s = trade.status?.toUpperCase();
|
|
15951
16009
|
const isSettled = s === "SETTLED" || s === "CONFIRMED" || s === "FILLED" || s === "ALLOCATED";
|
|
15952
16010
|
const isFailed = s === "SETTLEMENT_FAILED" || s === "REJECTED" || s === "CANCELLED" || s === "CANCELED";
|
|
15953
|
-
const isSettling =
|
|
16011
|
+
const isSettling = tradeIsSettling(trade.status);
|
|
16012
|
+
const stuckSettling = isSettling && isTradeStuck(trade);
|
|
15954
16013
|
const settlementLabel = isSettled ? "Settled" : isFailed ? "Settlement Failed" : isSettling ? prettyLabel(trade.status) : "\u2014";
|
|
15955
16014
|
const settlementMeta = isSettled ? { color: "#0ecb81", bg: "rgba(14,203,129,0.1)" } : isFailed ? { color: "#f6465d", bg: "rgba(246,70,93,0.12)" } : isSettling ? { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" } : null;
|
|
15956
16015
|
const sideColor = sideLabel(trade.side) === "Buy" ? "#0ecb81" : "#f6465d";
|
|
@@ -15993,7 +16052,10 @@ function PortfolioActivityPanel({
|
|
|
15993
16052
|
] }),
|
|
15994
16053
|
/* @__PURE__ */ jsxs(CDetailItem, { children: [
|
|
15995
16054
|
/* @__PURE__ */ jsx(CDLabel, { children: "Settlement" }),
|
|
15996
|
-
/* @__PURE__ */
|
|
16055
|
+
/* @__PURE__ */ jsxs(CDValue, { children: [
|
|
16056
|
+
settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : "\u2014",
|
|
16057
|
+
stuckSettling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: true, style: { marginLeft: 6 } })
|
|
16058
|
+
] })
|
|
15997
16059
|
] }),
|
|
15998
16060
|
/* @__PURE__ */ jsxs(CDetailItem, { children: [
|
|
15999
16061
|
/* @__PURE__ */ jsx(CDLabel, { children: "Date" }),
|
|
@@ -16018,7 +16080,8 @@ function PortfolioActivityPanel({
|
|
|
16018
16080
|
const s = trade.status?.toUpperCase();
|
|
16019
16081
|
const isSettled = s === "SETTLED" || s === "CONFIRMED" || s === "FILLED" || s === "ALLOCATED";
|
|
16020
16082
|
const isFailed = s === "SETTLEMENT_FAILED" || s === "REJECTED" || s === "CANCELLED" || s === "CANCELED";
|
|
16021
|
-
const isSettling =
|
|
16083
|
+
const isSettling = tradeIsSettling(trade.status);
|
|
16084
|
+
const stuckSettling = isSettling && isTradeStuck(trade);
|
|
16022
16085
|
const settlementLabel = isSettled ? "Settled" : isFailed ? "Settlement Failed" : isSettling ? prettyLabel(trade.status) : "\u2014";
|
|
16023
16086
|
const settlementMeta = isSettled ? { color: "#0ecb81", bg: "rgba(14,203,129,0.1)" } : isFailed ? { color: "#f6465d", bg: "rgba(246,70,93,0.12)" } : isSettling ? { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" } : null;
|
|
16024
16087
|
const sideColor = sideLabel(trade.side) === "Buy" ? "#0ecb81" : "#f6465d";
|
|
@@ -16035,7 +16098,10 @@ function PortfolioActivityPanel({
|
|
|
16035
16098
|
] }) }),
|
|
16036
16099
|
/* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price) }) }),
|
|
16037
16100
|
/* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price * trade.quantity) }) }),
|
|
16038
|
-
/* @__PURE__ */ jsx(GridCell, { children:
|
|
16101
|
+
/* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
|
|
16102
|
+
settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsx(CellText, { $muted: true, children: "\u2014" }),
|
|
16103
|
+
stuckSettling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: true })
|
|
16104
|
+
] }) }),
|
|
16039
16105
|
/* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatTimestamp(trade.executedAt) }) }),
|
|
16040
16106
|
/* @__PURE__ */ jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
16041
16107
|
/* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|