Skip to content

Feat/sidebar layers - #5

Merged
Aymericr merged 6 commits into
mainfrom
feat/sidebar-layers
Oct 26, 2025
Merged

Feat/sidebar layers#5
Aymericr merged 6 commits into
mainfrom
feat/sidebar-layers

Conversation

@Aymericr

Copy link
Copy Markdown
Contributor

No description provided.

@vercel

vercel Bot commented Oct 26, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
editor Ready Ready Preview Comment Oct 26, 2025 4:48am

@Aymericr
Aymericr merged commit c7925e8 into main Oct 26, 2025
2 checks passed
@Aymericr
Aymericr deleted the feat/sidebar-layers branch October 27, 2025 13:42
ju-code10 added a commit to ju-code10/aacsteel-designer-Pascal-fork that referenced this pull request May 4, 2026
Schemas (§3 data model) under packages/cfs/src/schema/:
- ids: branded UUIDs for every CFS entity; PascalNodeId relaxed to
  z.string().min(1) since Pascal uses prefix_<nanoid> ids, not UUIDs.
- primitives: geometry/material/role/header/opening/compliance enums +
  CFSProjectSettings.
- 7 node schemas (project, member library, wall framing, member, opening,
  panel, service hole, connection), all .strict() except metadata.
- invariants.ts: cross-schema runtime checks for §3.12 rules
  (reference integrity, geometry, type-conditional, panel non-overlap).

SSMA seed catalog at packages/cfs/src/data/ssma.json with 12 sections
(350/362/400/600 stud + track depths at 33 and 54 mil), plus
library/load-ssma.ts parser with formatted Zod errors.

Store (§4):
- use-cfs.ts expanded to full §4.2 shape with persist middleware
  partialized to the §4.10 allowlist (unitsDisplay, preferredHeaderType,
  activeLibraryId).
- setCFSMode(true) constructs a singleton CFSProject via
  useScene.createNode (one Zundo step, idempotent).
- setActiveLibrary performs the §4.8 cross-store dirty sweep over every
  cfs_wall_framing and cfs_member.
- loadLibrary validates and registers, auto-activating on first load.
- with-batched-undo.ts composes Pascal's pauseSceneHistory /
  resumeSceneHistory; cross-frame pendingBatchLabel deferred to Slice 3.
- selectors/: useCFSProject, useProjectSettings + updateProjectSettings,
  useActiveLibrary, useSectionById, useIsCFSMode, lib/memoize.

Editor wiring:
- apps/editor/cfs/components/CFSRoot.tsx hydrates SSMA on mount
  independent of isCFSMode.
- apps/editor/app/page.tsx mounts <CFSRoot /> alongside <ModeToggle />.

Tests: 58 across 9 files — schema round-trip, defaults, branded ids,
every §3.12 invariant, loader happy/failure, store actions, library
hydration, project lifecycle (one project / one Zundo step / no
duplicates), cross-store dirty sweep, withBatchedUndo (suppresses
entries, depth-counts nested calls, recovers on throw), selector
behavior + updateProjectSettings.

Test infrastructure: packages/cfs/bunfig.toml + test-setup.ts stub
three-mesh-bvh / three-bvh-csg (UMD bundles fail under Bun's CJS interop
when transitively loaded by core) and shim requestAnimationFrame /
localStorage for Pascal's updateNodesAction and Zustand's persist.

Spec drift to reconcile in spec slice G:
- §3.0 file-layout listing is PascalCase; this slice ships kebab-case
  per §0.5 and the use-cfs.ts precedent.
- §3.0 PascalNodeId uses z.string().uuid(); relaxed here to non-empty
  string for compatibility with Pascal's actual id format.
- §4 appendix items pascalorg#1 (Pascal pause/resume helpers) and pascalorg#5 (useCFS vs
  useCFSStore naming) are de facto resolved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 449b0336b98f2088523a5647cf371fd669b408ee)
ju-code10 added a commit to ju-code10/aacsteel-designer-Pascal-fork that referenced this pull request May 12, 2026
Production exporters for procurement (BOM xlsx), fabrication (cut list
csv), and panel-shop detailing (DXF zip). All client-side, downloaded
via a transient anchor click. Wired into a new `Export ▾` menu in the
top toolbar with per-item dry-run preflight; PDF / Scene JSON / Import
are rendered disabled with a "ships in Slice 9" tooltip so menu
placement is stable.

packages/cfs/src/exporters/
  - bom.ts (ExcelJS ^4.4.0) — Cover + per-panel + Totals tabs, real
    =SUM() formulas in the totals rows, built-up header expansion via
    HEADER_COMPONENTS (box→4, back-to-back→2, L-header→2,
    single-track→1, proprietary→1+note).
  - cut-list.ts — UTF-8 with BOM, CRLF, 15 cols, one row per physical
    CFSMember (no built-up expansion); service holes encoded as
    `pos@dia;…` (detailer holes only — mill pre-punches excluded per
    §6.2).
  - dxf.ts (@tarikjabiri/dxf ^2.8.0 + fflate ^0.8.2) — one DXF per
    panel, 14 spec layers, LWPOLYLINE rectangles for members, CIRCLE
    for service holes, DIMENSION entities for the horizontal + vertical
    chains, LINE+TEXT title block, fastener schedule on the NOTES
    layer. $INSUNITS = 4 (mm) or 1 (in). Zipped with fflate.
  - preflight.ts — shared §6.0 checks; `previewPreflight` is the dry
    run the menu uses to disable items with a tooltip explaining why.

packages/cfs/src/lib/
  - shipping-marks.ts (pure planner) + shipping-marks-apply.ts (scene
    write). Diff-only — re-export of an unchanged scene writes nothing
    and pushes no undo entry. Inside `withBatchedUndo('compute shipping
    marks')`.
  - scene-walk.ts — §6.0 stable iteration order
    (building createdAt → level elevation → wall → panel sequenceNumber
    → member shipping mark) + ancestry helpers + shortId.
  - csv.ts, slugify.ts, length-format.ts (mm/in/ft-in-16),
    header-type-resolver.ts, download.ts.

apps/editor/cfs/
  - components/toolbar/ExportMenu.tsx — `Export ▾` dropdown, far right.
    Click-outside close, per-item disabled state from previewPreflight.
  - components/ExportStatusBanner.tsx — top-anchored progress / success
    / error banner; success auto-dismisses after 6 s, error keeps until
    user clicks ✕.
  - lib/use-export.ts — useSyncExternalStore-backed singleton, FIFO
    depth-1 queue, shared by the menu, the banner, and the keyboard
    shortcuts. No new editor-side runtime deps.
  - lib/use-cfs-shortcuts.ts — Cmd/Ctrl+Shift+B (BOM) and
    Cmd/Ctrl+Shift+D (DXF) quick-exports; PDF / JSON / open-menu
    shortcuts defer to Slice 9.

Coverage: §6.0–§6.3, §6.6, §6.7 (pascalorg#1–4, pascalorg#6–8). 311 tests pass, 1 skip
(round-trip invariant pascalorg#5 waits on JSON in Slice 9), 0 fail. Per-pkg
type check clean.

Known reconciliations for spec slice G:
  - §6.1 says §5.1 emits ONE header member per opening, then BOM
    expands. Today's framing pass emits one CFSMember per box-header
    piece (FRM-S4-01:371), so real-editor BOM produces 4× expansion
    rows per box opening. Slice 8 exporters honour the spec contract;
    fixture matches it explicitly.
  - @tarikjabiri/dxf pinned to ^2.8.0; spec called for ^1.6.0, which
    never shipped to npm (1.x ends at 1.0.7). Same library, same
    maintainer, mature stable line.

Slice 9 polish-pass TODOs (captured in code TODOs):
  - Visual DXF verification in LibreCAD / AutoCAD / BricsCAD per §6.3
    open item pascalorg#6. If DIMENSION entities render as raw lines, swap to
    LINE+TEXT inside dxf.ts:drawDimensions.
  - Cmd/Ctrl+E open-menu, Cmd/Ctrl+Shift+E JSON, Cmd/Ctrl+Shift+P PDF
    quick-export shortcuts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
leapar added a commit to leapar/pascaleditor that referenced this pull request Aug 31, 2026
…ascalorg#3, pascalorg#6

- pascalorg#1: FitSceneButton now calls useTranslations() (was throwing
  ReferenceError on render).
- pascalorg#2: Command palette group keys use dotted form (commands.group.scene)
  to match the i18n catalog; previously used the flat form
  (commands.groupScene) which produced undefined labels.
- pascalorg#3: save-button.tsx migrated from the bespoke messages[] lookup to
  useTranslations() with save.* keys, removing the unprefixed key leak
  into the global namespace and matching the rest of the codebase.
- pascalorg#6: Added missing catalog keys with full en/zh parity:
    sidebar.build, sidebar.settings
    editor.openSavedScenes, editor.rotate, editor.place,
    editor.forcePlace, editor.guidedConstraintsBypassed

Skipped pascalorg#4 (resolveBaseUrl) and pascalorg#5 (editor-layout-v2 toolbar) — those
predate this branch and are out of scope for the i18n restore PR.
leapar added a commit to leapar/pascaleditor that referenced this pull request Sep 1, 2026
…calorg#5

Two regressions on the i18n restore branch predate the i18n work and
have stayed open across every Bugbot pass because they're outside that
work's scope. They're real bugs that need to ship, though — without
them the scenes page is empty in any deployed environment and the
viewer toolbar no longer sits flush to the right.

* apps/editor/app/scenes/page.tsx — Bug pascalorg#4: resolveBaseUrl was
  hardcoded to 'http://localhost:3000' when NEXT_PUBLIC_APP_URL is
  unset, so the scenes list always returned an empty array outside
  local development. Bring back the headers()-based host detection
  the same way upstream main does it: read x-forwarded-host (or
  fall back to host) and x-forwarded-proto (or fall back to 'http'),
  and only return the localhost sentinel if neither header is
  present. Restores the missing 'next/headers' import that the i18n
  commit dropped alongside this logic.
* packages/editor/src/components/editor/editor-layout-v2.tsx — Bug pascalorg#5:
  the viewer toolbar was wrapped in a three-column grid that placed
  toolbarRight in the center column and left the third column empty,
  pushing display, walkthrough, and preview controls away from the
  right edge. Restore the upstream flex layout — toolbarLeft at the
  start, toolbarRight at the end, both with 'justify-between' on the
  parent so they sit at opposite edges of the toolbar strip.

Both files typecheck clean.

Refs Bugbot reviews on PR pascalorg#740.
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.

1 participant