0.2.37: live funds above exited ones in the investor portal
A fully-exited fund/SPV card sinks to the bottom of the LP's stack instead of sitting between active funds (stable sort, shared by the LP portal and the admin Investor View). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1deb6586b0
commit
053bfeab23
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ten31portal-startos",
|
"name": "ten31portal-startos",
|
||||||
"version": "0.2.36",
|
"version": "0.2.37",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run check && rm -rf ./javascript && ncc build startos/index.ts -o ./javascript",
|
"build": "npm run check && rm -rf ./javascript && ncc build startos/index.ts -o ./javascript",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { v_0_2_36 as current } from './v_0_2_36'
|
export { v_0_2_37 as current } from './v_0_2_37'
|
||||||
import { v_0_1_0 } from './v_0_1_0'
|
import { v_0_1_0 } from './v_0_1_0'
|
||||||
import { v_0_2_0 } from './v_0_2_0'
|
import { v_0_2_0 } from './v_0_2_0'
|
||||||
import { v_0_2_1 } from './v_0_2_1'
|
import { v_0_2_1 } from './v_0_2_1'
|
||||||
@@ -35,4 +35,5 @@ import { v_0_2_32 } from './v_0_2_32'
|
|||||||
import { v_0_2_33 } from './v_0_2_33'
|
import { v_0_2_33 } from './v_0_2_33'
|
||||||
import { v_0_2_34 } from './v_0_2_34'
|
import { v_0_2_34 } from './v_0_2_34'
|
||||||
import { v_0_2_35 } from './v_0_2_35'
|
import { v_0_2_35 } from './v_0_2_35'
|
||||||
export const other = [v_0_1_0, v_0_2_0, v_0_2_1, v_0_2_3, v_0_2_4, v_0_2_5, v_0_2_6, v_0_2_7, v_0_2_8, v_0_2_9, v_0_2_10, v_0_2_11, v_0_2_12, v_0_2_13, v_0_2_14, v_0_2_15, v_0_2_16, v_0_2_17, v_0_2_18, v_0_2_19, v_0_2_20, v_0_2_21, v_0_2_22, v_0_2_23, v_0_2_24, v_0_2_25, v_0_2_26, v_0_2_27, v_0_2_28, v_0_2_29, v_0_2_30, v_0_2_31, v_0_2_32, v_0_2_33, v_0_2_34, v_0_2_35]
|
import { v_0_2_36 } from './v_0_2_36'
|
||||||
|
export const other = [v_0_1_0, v_0_2_0, v_0_2_1, v_0_2_3, v_0_2_4, v_0_2_5, v_0_2_6, v_0_2_7, v_0_2_8, v_0_2_9, v_0_2_10, v_0_2_11, v_0_2_12, v_0_2_13, v_0_2_14, v_0_2_15, v_0_2_16, v_0_2_17, v_0_2_18, v_0_2_19, v_0_2_20, v_0_2_21, v_0_2_22, v_0_2_23, v_0_2_24, v_0_2_25, v_0_2_26, v_0_2_27, v_0_2_28, v_0_2_29, v_0_2_30, v_0_2_31, v_0_2_32, v_0_2_33, v_0_2_34, v_0_2_35, v_0_2_36]
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { VersionInfo } from '@start9labs/start-sdk'
|
||||||
|
|
||||||
|
export const v_0_2_37 = VersionInfo.of({
|
||||||
|
version: '0.2.37:0',
|
||||||
|
releaseNotes: {
|
||||||
|
en_US:
|
||||||
|
"Investor portal ordering: live funds and SPVs now always appear above exited ones — a fully-exited position sinks to the bottom of the stack instead of sitting between active funds.",
|
||||||
|
},
|
||||||
|
migrations: {
|
||||||
|
up: async ({ effects }) => {},
|
||||||
|
down: async ({ effects }) => {},
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
// - content-hashed /assets/* are cache-first (immutable, safe forever)
|
// - content-hashed /assets/* are cache-first (immutable, safe forever)
|
||||||
// - /api/* is never cached
|
// - /api/* is never cached
|
||||||
// Bump CACHE on each release so old entries are purged.
|
// Bump CACHE on each release so old entries are purged.
|
||||||
const CACHE = 'ten31-portal-0.2.36'
|
const CACHE = 'ten31-portal-0.2.37'
|
||||||
|
|
||||||
self.addEventListener('install', () => self.skipWaiting())
|
self.addEventListener('install', () => self.skipWaiting())
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ export default function InvestorPortalView({
|
|||||||
accounts.filter((a) => a.exited_on).map((a) => `${a.entity_id}:${a.investor_user_id}`),
|
accounts.filter((a) => a.exited_on).map((a) => `${a.entity_id}:${a.investor_user_id}`),
|
||||||
).size;
|
).size;
|
||||||
|
|
||||||
|
// Live funds first; a fund where every position is exited sinks to the bottom so closed
|
||||||
|
// positions never sit between active ones. Stable sort keeps the original order otherwise.
|
||||||
|
const isClosed = (e: Entity) => {
|
||||||
|
const own = accounts.filter((a) => a.entity_id === e.id);
|
||||||
|
return own.length > 0 && own.every((a) => a.exited_on);
|
||||||
|
};
|
||||||
|
const ordered = [...entities].sort((a, b) => Number(isClosed(a)) - Number(isClosed(b)));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-8">
|
<div className="space-y-8">
|
||||||
{activeEntityCount > 1 && (
|
{activeEntityCount > 1 && (
|
||||||
@@ -44,7 +52,7 @@ export default function InvestorPortalView({
|
|||||||
exitedCount={exitedPositions}
|
exitedCount={exitedPositions}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{entities.map((e) => (
|
{ordered.map((e) => (
|
||||||
<FundSection
|
<FundSection
|
||||||
key={e.id}
|
key={e.id}
|
||||||
entity={e}
|
entity={e}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Bumped each release so the running build is visible in the UI.
|
// Bumped each release so the running build is visible in the UI.
|
||||||
// If the number shown in the app doesn't match the installed s9pk version,
|
// If the number shown in the app doesn't match the installed s9pk version,
|
||||||
// the new frontend isn't actually being served.
|
// the new frontend isn't actually being served.
|
||||||
export const APP_VERSION = "0.2.36";
|
export const APP_VERSION = "0.2.37";
|
||||||
|
|||||||
Reference in New Issue
Block a user