Skip to content

[1] PRO workflow overhaul, mobile support, loads/shells editing, and calc report hardening#45

Merged
diegokingston merged 25 commits into
mainfrom
pr/2-next-product-iteration
Jun 10, 2026
Merged

[1] PRO workflow overhaul, mobile support, loads/shells editing, and calc report hardening#45
diegokingston merged 25 commits into
mainfrom
pr/2-next-product-iteration

Conversation

@Batuis

@Batuis Batuis commented Mar 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

PRO mode overhaul with selection/delete correctness, grouped dropdown toolbar, editable data tables, mobile support, and calc report hardening.

Calc report hardening

  • Empty-report generation blocked when no analysis results exist
  • Truthful result provenance labeling (envelope / single combo / single case)
  • Report type always "Analysis Only" until design-check tables are rendered
  • Compact metadata block: report type + result basis
  • Cover page shows correct mode label (2D / 3D / PRO)

Saved-project / restore-mode fixes

  • Autosave now stores appMode (basico / educativo / pro)
  • Restore banner only appears in the matching mode
  • Banner reactively hides/shows on mode switch (no reload needed)
  • Legacy saves default to basico (conservative)

PRO toolbar and interaction overhaul

  • Desktop: grouped dropdown toolbar (Geometry, Properties, Conditions, Analysis)
  • Pan/Select tool buttons with select-subtype dropdown
  • Undo/Redo buttons with platform-aware Ctrl/Cmd+Z/Y shortcuts
  • Expanded labels: Connections, Diagnostics (no abbreviations) across all 14 locales
  • Row-selection sync: clicking rows in Results/Design/Verification/Nodes/Members/Shells/Supports/Loads highlights entities in viewport
  • Select-mode filtering enforced for click and box selection per subtype
  • Shell/element ID overlap disambiguation using selectMode throughout selection, highlighting, status bar, and deletion
  • Tab-entry and row-click auto-align selectMode to prevent wrong-entity selection

PRO tables and editing workflows

  • Shells: editable material (dropdown) and thickness (input) via new updatePlate/updateQuad methods
  • Loads: all 5 sub-tables (nodal, distributed, point, surface, thermal) are inline-editable
  • Load cases: converted from cramped tabs to editable table rows (type selector, name input, load count, visibility toggle)
  • Combinations: card layout with per-factor rows (factor × case name)
  • Self-weight: surfaced as display-only D row with checkbox toggle, defaults ON in PRO
  • Lr added to load-case type selector
  • Load-case row selection highlights all loads using that case
  • Consistent row hover/selected/cursor affordance with teal left-bar indicator across all data tabs
  • Status bar separates shell count from element count, shows supports and loads

3D interaction improvements

  • Measure tool: direct node raycast + screen-space nearest-node snap (works above grid, through load glyphs)
  • Shell selection: opacity boost 0.45 → 0.85 for clear selected state
  • Load hover/selection visual feedback with color change
  • Load highlight sync uses userData.id (stable model index) instead of visual child index

7-story RC example cleanup

  • Load-case names translated to English (preserving engineering specificity)
  • Wind combinations corrected: U4–U7 now use factor 1.6 (ASCE 7 / CIRSOC)
  • Dead-load composition visible: self-weight separated from superimposed dead in combination cards

Mobile support

  • PRO upper toolbar: Pan / Undo / Redo / Results-Solve / Select
  • Persistent Select sub-mode strip (stays open while Select is active)
  • Floating Results/Solve panel (upper-left, tight under toolbar)
  • Mode selector: styled dropdown with Education (Beta) / PRO (Beta)
  • Examples dialog: full-width on mobile with text wrapping
  • Floating Results/Solve box hidden in Education/PRO (Basic-only toggle preserved)

i18n

  • StatusBar: shells/loads labels via i18n keys
  • ProLoadsTab: Type, Name, Loads, ON/OFF, auto, Add Load, selected nodes via i18n keys
  • Analysis dropdown: Connections/Diagnostics expanded across all 14 locales

Not included / intentionally deferred

  • No load-case physical-template inheritance (load cases are identity containers; no per-load override tracking)
  • No solver changes
  • No localized example-content system (example data uses authored English names)
  • No separate selectedShells storage (uses selectMode disambiguation on shared selectedElements)
  • No full design-check tables in calc report yet (report type stays "Analysis Only")

@Batuis Batuis changed the title [2] Basic structural calc-book report (PDF via browser print) [2] NOT READY - Basic structural calc-book report (PDF via browser print) Mar 29, 2026
@Batuis Batuis marked this pull request as draft March 29, 2026 22:47
Batuis added 5 commits March 31, 2026 22:07
…ts, forces

Complete HTML report generator with 5 sections:
1. Model Data — materials, sections, nodes, elements, supports (condensed for large models)
2. Loads — load cases, combinations with factors, applied load summary
3. Reactions — per-node reactions with equilibrium check (ΣF ≈ 0)
4. Displacements — max displacement summary box + sorted table (top 20 for large models)
5. Internal Forces — force summary + per-element start/end forces

Both 2D (N/V/M) and 3D (N/Vy/Vz/Mx/My/Mz) results supported.
Pre-report dialog for project name, engineer, company, notes.
Print-friendly CSS with page breaks. Blob URL approach (same as PRO report).
Report triggered from existing PDF button in ToolbarProject.
i18n keys for en/es.
New module: design-check-results.ts
- MemberDesignResult: unified per-member shape with elementId, elementType,
  sectionName, governingCheck, utilization, status, comboName, checks[]
- CheckDetail: per-check demand/capacity/ratio/status
- DesignCheckSummary: aggregate pass/warn/fail counts

Adapters:
- normalizeCirsoc201: CIRSOC 201 RC (JS) → unified
- normalizeCirsoc301: CIRSOC 301 steel (JS) → unified
- normalizeWasmSteel: AISC 360 / EC3 (WASM snake_case) → unified
- normalizeWasmRC: ACI 318 / EC2 (WASM snake_case) → unified

verificationStore expanded:
- New setDesignResults() for unified multi-code results
- designMap for O(1) element lookup
- getMaxRatio/getStatus check unified results first, legacy fallback
- Existing CIRSOC/steel legacy paths preserved

Tests: 8 focused tests covering all 4 adapters + summary builder.
New ProDesignTab.svelte — unified design-check product surface:
- Code selector (CIRSOC / ACI-AISC / Eurocode / NDS / Masonry / CFS)
- 'Run Design Check' button that dispatches to the selected code
- Summary bar: total members, pass/warn/fail counts (color-coded)
- Member utilization table sorted worst-first:
  Element | Type | Section | Governing Check | Utilization (ratio bar) | Status | Combo
- Status filter (All / Fail / Warn / Pass)
- Ratio bars: green(≤0.5) → yellow → amber → orange → red(>1.1)
- Auto-activates verification viewport overlay on check completion

Integration:
- Wired as 'design' tab in PRO panel (between Results and Verification)
- Added to PRO nav strip in App.svelte
- Uses normalized results from Chunk 1 via verificationStore.setDesignResults
- CIRSOC path also populates legacy store for viewport compatibility
- i18n keys for en/es
Toasts now have a small × in the top-right corner for immediate dismissal.
Auto-dismiss still works as before (4s/8s timeout). The dismiss button is
semi-transparent and highlights on hover. Added dismissToast(id) to uiStore.
@Batuis Batuis force-pushed the pr/2-next-product-iteration branch from 8ed6300 to 351de92 Compare April 1, 2026 01:08
@Batuis Batuis changed the title [2] NOT READY - Basic structural calc-book report (PDF via browser print) [1] NOT READY - Basic structural calc-book report (PDF via browser print) Apr 1, 2026
@Batuis Batuis changed the base branch from pr/1-recovery-landing-mobile-basic3d to main April 1, 2026 01:18
…lc report hardening

Calc report:
- empty-report guard, truthful result provenance, analysis-only metadata
- report type, result basis, and contents block

Saved-project restore:
- mode-aware autosave with reactive banner that hides/shows on mode switch

PRO toolbar:
- grouped dropdown desktop toolbar (Geometry, Properties, Conditions, Analysis)
- Pan/Select tools with subtype filtering
- undo/redo buttons and Ctrl/Cmd+Z/Y shortcuts
- expanded Analysis dropdown labels (Connections, Diagnostics) across all locales

PRO selection/delete:
- select-mode filtering for click and box selection
- shells picking via raycasting shellsParent
- loads picking with line threshold for ArrowHelper shafts
- correct highlight sync using userData.id for loads
- selectMode disambiguation for overlapping shell/element IDs
- row-click selection sets selectMode to match entity type
- tab-entry auto-aligns selectMode
- delete respects selectMode for shell/element disambiguation

PRO tables:
- shells editable (material, thickness) with updatePlate/updateQuad
- loads editable across all 3D load types including surface3d and thermalQuad3d
- load cases as editable table rows with type selector, name input, load count
- combination cards with per-factor rows (factor × case name)
- self-weight surfaced as display-only D row with ON/OFF toggle
- Lr type support in load-case selectors
- load-case row selection highlights all loads using that case
- consistent row hover/selected/cursor affordance across all data tabs
- selection bar separates shells from elements, shows supports and loads

3D viewport:
- measure tool node snapping via direct raycast + screen-space proximity
- shell selection with opacity boost (0.45 → 0.85) for legibility
- load hover/selection highlight with visual feedback

7-story RC example:
- English load-case names
- wind combinations corrected to 1.6W (U4-U7)

Mobile PRO:
- upper toolbar with Pan/Undo/Redo/Results-Solve/Select
- persistent Select sub-mode strip
- floating Results/Solve panel (upper-left, shared with Basic via mode gate)
- mode selector as styled dropdown with Beta labels
- examples dialog full-width on mobile with text wrapping
- floating Results/Solve box hidden in Education/PRO (Basic-only)

i18n:
- shells/loads status labels
- PRO loads tab labels (Type, Name, Loads, ON/OFF, auto, etc.)
@Batuis Batuis changed the title [1] NOT READY - Basic structural calc-book report (PDF via browser print) [1] PRO workflow overhaul, mobile support, loads/shells editing, and calc report hardening Apr 3, 2026
@Batuis Batuis marked this pull request as ready for review April 3, 2026 22:09
Batuis added a commit that referenced this pull request Apr 20, 2026
Batuis and others added 4 commits April 30, 2026 13:15
Resolves typed-Release conflicts (Viewport3D.svelte, store/file.ts,
viewport3d/scene-sync.ts) by adopting main's typed Release per-element-end
structure while preserving pr/2's appMode persistence in DedalFile.
Debug-mode perf gate; the harmonic solver itself has not regressed
since the modal-superposition speedup in March. CI saw 18.2s on a
slow runner (locally on Apple Silicon: ~9s debug, ~80ms release), so
the 15s bound was too tight for shared GitHub Actions hardware.

Bumping to 30s gives headroom for runner variance while still catching
real regressions (e.g., losing the modal-superposition shortcut would
push this back into the multi-minute range).
Avoids libtest harness rejecting --sample-size by listing the three criterion [[bench]] targets (solver_bench, assembly_bench, workflow_bench) explicitly. No engine source change.
diegokingston and others added 6 commits June 1, 2026 15:54
…+ report)

Addresses several bugs surfaced reviewing the design-check / calc-report
work. Web suite: 2120 passing (5 skipped); vite build clean.

- design-check-results: a WASM result with no recognized ratio fields no
  longer normalizes to utilization 0 / status 'ok' (a falsely-green,
  never-verified member). Such members now surface as 'fail' /
  "Not checked". An explicit unity_ratio of 0 is still honored as a real
  pass. Covers normalizeWasmSteel + normalizeWasmRC; adds tests.
- design-check-results: remove dead `worstStatus` helper.
- ProDesignTab: pass the governing-combos map (3rd arg) to
  autoVerifyFromResults so the Design tab's "Combo" column is populated,
  matching ProPanel/Verification-tab behavior.
- CalcReportDialog: distributed-load and nodal-moment descriptions used `??`,
  so a present-but-zero component on one axis shadowed the real value on
  another (qZI=0 hid qYI=5 -> "q=0"). Use `||` to fall through zeros.
- ProLoadsTab: inline load-edit cells used `parseFloat(value) || 0`, which
  truncated comma decimals ("1,5" -> 1) for es/de/fr users. Route through a
  shared locale-aware `parseNum` helper.

Not fixed here (need a product/data-model decision, see review):
- "aci-aisc"/"eurocode" run both RC and steel WASM checks on every member
  (neither Rust check filters by material, and Material has no category to
  route on) -> double-counted members + last-writer-wins overlay. Needs a
  material category on the model to route concrete->ACI, steel->AISC.
deserializeProject wrote uiStore.appMode, but appMode is a getter-only
property derived from analysisMode — the strict-mode assignment threw a
TypeError on every load of a file saved with the appMode field, aborting
the restore midway (analysisMode/axis convention never applied, stale
results kept). Restoring analysisMode alone already yields the right
appMode.
…eletion by id

- Infer appMode for pre-appMode autosaves from analysisMode instead of
  defaulting to basico, so a legacy PRO autosave still shows its restore
  banner on /pro.
- Skip the 30s autosave write while the model is empty: the loader
  ignores empty snapshots, and the write would destroy a pending save
  from another mode whose banner is hidden by the mode-match gate.
- After restoring an autosave, sync currentAppMode + URL with the
  restored analysisMode so UI mode and route can't desync.
- Stop forcing includeSelfWeight=true on every PRO entry (switchAppMode
  and onMount): selfWeightPro already defaults ON, and the forced write
  silently reverted a user's explicit opt-out on every mode round-trip,
  double-counting gravity on the next solve.
- handleProKeydown now deletes selected loads by data id (see the
  selection-unification commit): index-based resolution deleted the
  wrong loads once the array had been mutated by the table's × button.
The set was written with data ids by the 2D viewport and
SelectedEntityPanel but with array indices by ProLoadsTab and the two
keyboard delete handlers, so Delete removed the wrong load in basico
(ids start at 1, indices at 0) and resolved stale indices in PRO after
any table-side deletion. Unify on data ids:

- ProLoadsTab: select/highlight rows by data id (also drops the
  per-row findIndex scan — O(L) instead of O(L^2) per render — and
  batch-assigns the case selection in one store write instead of one
  Set copy per load).
- Toolbar (basico): restore the pre-PR delete-by-id behavior.
- ProLoadsTab ×-button prunes the deleted id from the selection.
…consistency

Frame elements and plates/quads have independent id counters but share
uiStore.selectedElements, disambiguated only by selectMode. The 3D
viewport ignored selectMode for click and box selection, so with the
Shells tab open (which auto-flips selectMode to 'shells') clicking a
beam and pressing Delete removed the quad with the same id.

- Viewport3D click selection now filters per select subtype (mirroring
  the 2D viewport) and adds shell picking in shells mode via the
  plate/quad mesh userData.
- Box selection only gathers nodes/elements in the modes where they are
  the selection target.
- selectMode changes that cross the elements<->shells boundary clear
  selectedElements (single helper used by the setter and the
  proActiveTab auto-align), so stale ids can't be reinterpreted as the
  other entity type.
- Selection highlight honors the mode: frame elements don't light up
  for selected shell ids (scene-sync syncSelection + restoreColor),
  ProShellTab rows only show selected in shells mode, and selected
  shells get a visible opacity boost (0.45 -> 0.85).
- verificationStore.setConcrete/setSteel now invalidate the unified
  designMap: getMaxRatio/getStatus give it priority, so a fresh
  Verification-tab CIRSOC run otherwise kept painting the viewport with
  an older Design-tab run's results.
- ProDesignTab publishes results only after the empty-result guard,
  which now also covers the CIRSOC branch (an all-steel model checked
  zero members but still rendered a '0 members' success summary and
  flipped the viewport overlay).
- Each successful design run starts from a cleared store so legacy and
  unified results can't mix across codes.
…ect name

- The 'Equilibrium check' tested sum(reactions) ~ 0, but the solver
  convention is sum(reactions) = -sum(applied) (see
  engine/tests/solver_invariants.rs), so every loaded model printed
  'Review' in the deliverable and only unloaded models passed. Replace
  the bogus verdict with a factual note (and an envelope-specific note,
  since envelope per-node extremes don't sum to a load balance).
- Condensed applied-loads table numbers tail rows by their true
  positions (N-4..N) instead of continuing the counter at 32..36.
- CalcReportDialog re-seeds the project name from the current model on
  open: the always-mounted component captured the startup name once.
- Add regression tests for the reactions note and row numbering.
…light precedence

Review-pass fixes on this branch's own changes:

- ProLoadsTab's per-row x buttons did not stop propagation, so the
  click bubbled to the row's onclick and re-selected the just-deleted
  load id (phantom selection that swallowed the next Delete keypress
  and pushed a junk undo entry). Add stopPropagation (matching the
  case-row delete button) and restore an existence guard in
  selectLoadById.
- Plate and quad id counters are independent and can collide; deletion
  resolves ambiguous shell ids plate-first, so the 3D shell highlight
  and the quad table rows now mirror that precedence instead of
  highlighting both entities for one selected id. Root fix (typed or
  globally unique shell ids) left as follow-up.
…eview round

Fixes: file-load TypeError (derived appMode), autosave reachability and
empty-overwrite data loss, forced self-weight reset, selectedLoads id
unification, 3D selectMode enforcement + shell/element id consistency,
design-check stale overlay and empty-run guard, calc-report equilibrium
note / row numbering / project name.
…-product-iteration

Conflict in engine/tests/perf_regression_advanced.rs: both sides bumped
the harmonic gate 15s->30s with different doc comments; kept main's,
which documents the single-threaded CI execution.
'Run criterion benchmarks (quick)' timed out at 10 minutes on a slow
shared runner and turned the test job red with no correctness signal —
'Run all tests' had passed. The step is informational (reports are
uploaded as artifacts, with if: always()), so mark it
continue-on-error and give it a bit more headroom, following the same
rationale as the perf-gate contention fix (#52).
@diegokingston diegokingston merged commit 76f7319 into main Jun 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants