diff --git a/deploy/package.json b/deploy/package.json index 6aaf228..a30403e 100644 --- a/deploy/package.json +++ b/deploy/package.json @@ -1,6 +1,6 @@ { "name": "ten31portal-startos", - "version": "0.2.36", + "version": "0.2.37", "private": true, "scripts": { "build": "npm run check && rm -rf ./javascript && ncc build startos/index.ts -o ./javascript", diff --git a/deploy/startos/install/versions/index.ts b/deploy/startos/install/versions/index.ts index 8748dc9..4d0ed9c 100644 --- a/deploy/startos/install/versions/index.ts +++ b/deploy/startos/install/versions/index.ts @@ -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_2_0 } from './v_0_2_0' 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_34 } from './v_0_2_34' 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] diff --git a/deploy/startos/install/versions/v_0_2_37.ts b/deploy/startos/install/versions/v_0_2_37.ts new file mode 100644 index 0000000..44caedd --- /dev/null +++ b/deploy/startos/install/versions/v_0_2_37.ts @@ -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 }) => {}, + }, +}) diff --git a/frontend/public/sw.js b/frontend/public/sw.js index 2039b3e..815cba6 100644 --- a/frontend/public/sw.js +++ b/frontend/public/sw.js @@ -3,7 +3,7 @@ // - content-hashed /assets/* are cache-first (immutable, safe forever) // - /api/* is never cached // 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()) diff --git a/frontend/src/portal/InvestorPortalView.tsx b/frontend/src/portal/InvestorPortalView.tsx index d778ff1..208091a 100644 --- a/frontend/src/portal/InvestorPortalView.tsx +++ b/frontend/src/portal/InvestorPortalView.tsx @@ -35,6 +35,14 @@ export default function InvestorPortalView({ accounts.filter((a) => a.exited_on).map((a) => `${a.entity_id}:${a.investor_user_id}`), ).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 (