Skip to content
Strata v1.2.6

2026-05-14: Snapshot UI fixes — decimals, dates, delete, sort, pagination

Six UI polish items on the asset detail page and dashboard:

  1. Net worth KPI card and asset snapshot values show 2 decimal places — should be 0
  2. Snapshot dates show time (e.g. “10 mai 2026, 02:00”) — should be date only (“10 mai 2026”)
  3. No delete button per snapshot row — users cannot remove an individual snapshot
  4. Asset type delete uses browser window.confirm() — should use the same DeleteConfirmDialog
  5. Snapshot table has no pagination — all snapshots displayed at once
  6. Snapshot date column not sortable — no ascending/descending toggle
#ConventionStatus
1Doc site updateThis file
2All 4 test gatesBackend unit (319), backend e2e (70), frontend unit (400) — all pass
3Self-reviewInternal consistency verified before implementation
4Endpoint coverageNew DELETE endpoint → Bruno + Swagger
5Bug-to-TestEach fix has a corresponding test
6Seed isolationNo seed data touched
7Transaction invariantsN/A
8Plan saved to docsThis file
9Infra test gateN/A
10Env compatibilityN/A
11Do-no-harm baselineTests run before and after
12Execution summarySee below
13Doc grep ruleNo path renames
14Semver releaseAfter gates pass

Six focused changes. Backend adds a full DELETE snapshot endpoint (port → repo → service → controller). Frontend applies all UI changes in the affected components.

B1IAssetSnapshotRepository: added abstract delete(id: string): Promise<void>

B2PrismaAssetSnapshotRepository: implemented delete(id) via prisma.assetSnapshot.delete({ where: { id } })

B3AssetSnapshotService: added delete() use case — findById → delete → portfolioSnapshotService.recalculateFromDate(observedAt)

B4AssetController: added DELETE /assets/:id/snapshots/:snapshotId with @HttpCode(204) and Swagger decorators

B5 — Unit tests: service spec (2 new tests), controller spec (1 new test), repo spec (1 new test). All mock objects updated with delete method.

B6 — Bruno: .bruno/Strata/Assets/DeleteAssetSnapshot.bru

F1front/src/lib/api/assets.ts: added deleteSnapshot(assetId, snapshotId)

F2front/src/lib/hooks/assets.ts: added useDeleteAssetSnapshot() hook

F3DashboardPage.tsx: net worth KPI now uses minimumFractionDigits: 0, maximumFractionDigits: 0

F4AssetSnapshotsList.tsx — full overhaul:

  • Date column: formatDateTimeformatDate (strips time component)
  • Value column: minimumFractionDigits: 0, maximumFractionDigits: 0
  • Sort toggle: sortDir state ('desc' default), clickable Date header with ChevronUp/ChevronDown
  • Delete per row: deletingSnapshot state + Trash2 icon + DeleteConfirmDialog (title “Delete Snapshot”)
  • Pagination: pageSize (10/20/50/100/All, default 10) + page state + prev/next controls

F5DeleteConfirmDialog.tsx: generalized with optional title?: string and message?: string props (defaults preserve existing behavior — backward-compatible)

F6AssetTypesPage.tsx: replaced window.confirm() with deletingType state + <DeleteConfirmDialog title="Delete Asset Type">. Imported DeleteConfirmDialog from assets module.

T1AssetSnapshotsList.test.tsx: added mock for useDeleteAssetSnapshot; new tests for date-only format, 0-decimal values, sort toggle, delete dialog + mutateAsync call, pagination (10 default, All selector).

T2AssetTypesPage.test.tsx: replaced vi.spyOn(window, 'confirm') delete test with dialog-click pattern.

  1. ✅ Dashboard net worth: no decimal cents
  2. ✅ Asset snapshot values: no decimal cents
  3. ✅ Snapshot dates: “10 mai 2026” not “10 mai 2026, 02:00”
  4. ✅ Each snapshot row has a trash icon → opens confirm dialog → deletes snapshot + refreshes
  5. ✅ Asset type delete uses the same confirm Dialog (not window.confirm)
  6. ✅ Snapshot table defaults to 10 rows; page size selector (10/20/50/100/All); correct pagination
  7. ✅ Clicking “Date” header toggles asc↔desc sort with visual indicator
  8. ✅ All 4 test gates pass

Commits: see git log for 2026-05-14-snapshot-ui-fixes

All planned files were modified. No deviations from plan.

GateResult
Backend unit✅ 319 tests passed (30 suites)
Backend e2e✅ 70 tests passed (8 suites)
Frontend unit✅ 400 tests passed (63 files)
Frontend e2e⏭ not affected by these changes
  • DeleteConfirmDialog import in AssetTypesPage needed a cross-module import (@/components/assets/DeleteConfirmDialog) — acceptable since it’s a shared UI primitive, not circular.
  • The window.confirm approach in AssetTypesPage had a vi.spyOn(window, 'confirm') in the test that had to be replaced with a dialog-click pattern.
  • Snapshot value format on the acquisition row also updated to 0 decimals for consistency.