Skip to content

Commit e62d740

Browse files
committed
feat(layout): Forms geometry as native APEX components, with a mapping report (1.1.0)
One resolved layout model (apexlayout) feeds the exporter and the preview: canvases, frames and tab pages become regions, sub-regions and tab pages on the 12-column grid; rows come from the Forms geometry with a unit tolerance, column spans from each item's share of its parent, the label keeps its own share of the row, and items beside or below a frame keep their vertical order in derived row regions. Multi-record blocks on a table become interactiveGrid regions with one column per item in Forms order (headings, native types, primary key, widths, required, hidden columns, saved report); editing stays off until the block's DML is confirmed. Native item types carry their Forms properties: datePicker and numberField with format masks, textarea with width and height, checkbox values, radioGroup columns without the empty choice, selectList on a shared static LOV, readOnly, textCase, help text. Template options are native properties; stacked canvases and secondary windows become inline dialogs. Every export writes a per-element layout mapping report in the manifest (source identity, geometry, target, grid placement, rule, preserved properties, approximations, unsupported, missing metadata, status with explicit denominators). Button ids and grid column names come from one place so the page file, the manifest and the report agree. Verified on APEX 26.1.0: validate, import into a dedicated dev app, dictionary checks, and the page rendered through ORDS as a temporary end user (examples/verify/apex_render_check.py; no page made public). Docs: the mapping matrix with before/after, and the verification runbook rewritten. Tests: tests/test_apexlayout_fidelity.py (895 passed, 1 skipped in the full suite).
1 parent 0b03ac6 commit e62d740

19 files changed

Lines changed: 2419 additions & 166 deletions

CHANGELOG.md

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,72 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.1.0] — 2026-09-05
11+
12+
The layout release: a Forms screen becomes native APEX components that keep
13+
its structure — regions, sub-regions, tab pages, Interactive Grids, native
14+
item types, Universal Theme template options — with a per-element mapping
15+
report in every export and a login-based render check that never makes a
16+
page public.
17+
18+
### Added
19+
20+
- Layout model (`apexlayout.py`, one resolved layout shared by the exporter
21+
and the preview): rows detected with a tolerance in Forms units, column
22+
spans per parent width, the label's share of the row kept apart from the
23+
item's, nested frames as sub-regions, items drawn beside or below a frame
24+
in derived row regions that keep the vertical order of the screen.
25+
- Multi-record blocks on a table become `interactiveGrid` regions: one
26+
column per item in the order Forms draws the record, headings from the
27+
prompts, native column types, `primaryKey`, widths in characters,
28+
required and max length, hidden database items as hidden columns,
29+
non-database items with `source { type: none }`, a primary saved report.
30+
Editing stays off until the block's DML is confirmed, and no table is
31+
invented for a block without a query data source.
32+
- Native item types with their Forms properties: `datePicker` and
33+
`numberField` with `formatMask` (and `numberAlignment: end`), `textarea`
34+
with `width` / `height` from the item box, `checkbox` with the item's
35+
checked and unchecked values, `radioGroup` with `noOfCols` and no empty
36+
choice, `selectList` on a shared static LOV, `readOnly` for disabled
37+
items, `textCase`, help text from hint and tooltip.
38+
- Universal Theme template options as native properties:
39+
`t-Form--stretchInputs` on form regions and `t-IRR-region--hideHeader`
40+
on a grid that sits inside a captioned frame.
41+
- Stacked canvases and secondary windows as `inline-dialog` regions;
42+
toolbar canvases as blank regions with their controls in flow;
43+
boilerplate text and rectangles as static regions; a frame whose only
44+
content is a multi-record block hands its caption to the grid.
45+
- Per-element layout mapping report in `apexlang-manifest.json`
46+
(`layout.mapping_report`): source identity, canvas, geometry, target
47+
component and grid placement, the rule applied, preserved properties,
48+
approximations, unsupported mappings, missing metadata, and a
49+
`faithful` / `approximation` / `unsupported` status with explicit
50+
denominators — never a score.
51+
- Preview: the planned APEX layout is drawn from the same resolved model
52+
the export writes — Interactive Grids with their columns, date and
53+
number shapes, a fidelity badge per control, Faithful / Approximated /
54+
Unsupported / Grid columns counters.
55+
- `examples/verify/apex_render_check.py`: renders an imported page through
56+
ORDS as a temporary workspace end user that the script creates and
57+
removes (password never on the command line), then inspects the HTML.
58+
- `docs/layout-mapping-matrix.md`: the mapping matrix (source element,
59+
native target, properties preserved, verified support, fallback, known
60+
differences), the geometry-to-grid rules, the showcase denominators, the
61+
before/after of the rendered page and the commands that reproduce it.
62+
- `tests/test_apexlayout_fidelity.py`: every visible control placed exactly
63+
once, label spans always smaller than item spans
64+
(`LABEL_COLUMN_SPAN_TOO_BIG`), grid columns and button identifiers
65+
traceable from the report to the page file, unsupported item types
66+
reported as such, no custom JavaScript or CSS in the page.
67+
1068
### Changed
1169

70+
- Button identifiers and grid column names come from one place
71+
(`apexlayout.button_id`, `apexlayout.column_name`), so the page file,
72+
the manifest and the mapping report name every component the same way.
73+
- `docs/apex-import-verification.md`: the render-time check logs in as a
74+
temporary end user instead of making the page public, and reads the
75+
APEX dictionary before the HTML.
1276
- README: screenshots refreshed from the 1.0 workbench on the showcase
1377
module — review and CLI conversion, Doc (overview, block, triggers),
1478
Preview (Forms canvas next to the APEX page), Diff, the export dialog
@@ -761,7 +825,8 @@ build yet -- the roadmap item in `README.md` stays unchecked until it has.
761825
CLI providers (Claude Code, Codex), offline Echo mode, APEXlang 26.1
762826
export ZIP, Windows desktop app (Tauri) with MSI and NSIS installers.
763827

764-
[Unreleased]: https://github.com/B2DEV-TECH/FormsLang/compare/v0.1.8...HEAD
828+
[Unreleased]: https://github.com/B2DEV-TECH/FormsLang/compare/v1.1.0...HEAD
829+
[1.1.0]: https://github.com/B2DEV-TECH/FormsLang/compare/v1.0.0...v1.1.0
765830
[0.1.6]: https://github.com/B2DEV-TECH/FormsLang/compare/v0.1.5...v0.1.6
766831
[0.1.5]: https://github.com/B2DEV-TECH/FormsLang/compare/v0.1.4...v0.1.5
767832
[0.1.4]: https://github.com/B2DEV-TECH/FormsLang/compare/v0.1.3...v0.1.4

README.md

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -744,12 +744,16 @@ after every export.
744744
The ZIP is deliberately separate from the audit artifacts. Only approved
745745
proposals are included, and they are emitted as disabled page-process
746746
candidates until their execution point and condition are confirmed in Page
747-
Designer. Regions and page items are a migration scaffold — every Forms
748-
item lands on the page's 12-column grid at its canvas position, `MultiLine`
749-
text items become `textarea`, display-only items become `displayOnly`,
750-
Date and Number items deliberately stay `textField` until the richer
751-
keywords have been through a live validate — and schema binding, LOVs,
752-
validations and application navigation still require functional review.
747+
Designer. Regions and page items are native components on the page's
748+
12-column grid: canvases, frames and tab pages become regions, sub-regions
749+
and tab pages; single-record blocks become page items of the native type
750+
(`textarea`, `displayOnly`, `datePicker`, `numberField`, `checkbox`,
751+
`radioGroup`, `selectList`); multi-record blocks on a table become
752+
Interactive Grids with their columns in Forms order; and every export
753+
carries a per-element mapping report — see
754+
[docs/layout-mapping-matrix.md](docs/layout-mapping-matrix.md). Schema
755+
binding, LOVs, validations and application navigation still require
756+
functional review.
753757

754758
### Validate and import
755759

@@ -785,8 +789,10 @@ apex import -input orders.apex.zip
785789

786790
`validate` proves the package compiles; it cannot see a defect that only
787791
appears when a page is rendered. The repeatable procedure for that last
788-
mile — import, make the page public, fetch it through ORDS, read the HTML —
789-
is in [docs/apex-import-verification.md](docs/apex-import-verification.md).
792+
mile — import, log in as a temporary end user, fetch the page through ORDS,
793+
read the HTML, remove the user — is in
794+
[docs/apex-import-verification.md](docs/apex-import-verification.md), and
795+
`examples/verify/apex_render_check.py` does exactly that.
790796

791797
### What lands in APEX
792798

@@ -820,13 +826,16 @@ is in [docs/apex-import-verification.md](docs/apex-import-verification.md).
820826
the required marks Forms declared.</sub>
821827
</p>
822828

823-
> **Note — the layout of the converted application is being improved.** What
824-
> you see above is the scaffold 1.0 exports today: correct placement, correct
825-
> item types, correct required flags, but item widths, label alignment and
826-
> region packing still read as a migration scaffold rather than a finished
827-
> page. Tightening that layout is the current work on the exporter. Schema
828-
> binding, LOVs, validations and navigation remain the functional review
829-
> described above.
829+
> **Note — the screenshots above show the 1.0 layout.** Since 1.1 the
830+
> exporter turns the Forms geometry into native components with their own
831+
> widths, label placement and region packing — frames as sub-regions,
832+
> multi-record blocks as Interactive Grids, dates and numbers as Date
833+
> Pickers and Number Fields, Universal Theme template options — and each
834+
> export ships a per-element mapping report with explicit denominators.
835+
> [docs/layout-mapping-matrix.md](docs/layout-mapping-matrix.md) has the
836+
> mapping matrix and the before/after of the showcase page at the same
837+
> viewport. Schema binding, LOVs, validations and navigation remain the
838+
> functional review described above.
830839
831840
## Versioning Forms and APEXlang in git
832841

@@ -952,13 +961,13 @@ formslang/
952961
├── report.py # self-contained HTML + JSON
953962
├── formdoc.py # `doc`: the module's technical reference
954963
├── formdiff.py # `diff`: structural diff between two revisions
955-
├── formui.py # `preview`: canvases next to the APEX items they become
964+
├── formui.py # `preview`: Forms canvases next to the planned APEX layout (same model as the export)
956965
├── ai.py # provider layer (urllib only) + CLI providers + offline stub
957966
├── config.py # the settings file the in-app Settings screen writes
958967
├── secrets.py # the OS credential store: Credential Manager / Keychain / libsecret
959968
├── convert.py # conversion tasks, the doctrine prompt, answer parsing
960969
├── store.py # SQLite session: proposals, decisions, settings, audit trail
961-
├── apexlayout.py # Forms canvas geometry -> the APEX 12-column grid
970+
├── apexlayout.py # the shared layout model: geometry -> regions, grid rows, Interactive Grids, mapping report
962971
├── apexlang.py # APEXlang 26.1 project + deterministic import ZIP
963972
├── apeximport.py # SQLcl driver: validate / import, password on stdin only
964973
├── authstore.py # organizations, users, roles, sessions, MFA (auth.db)
@@ -969,6 +978,7 @@ formslang/
969978
desktop/ # Tauri 2 shell: native window, engine sidecar, MSI/NSIS
970979
packaging/ # PyInstaller entry: freezes the engine into one .exe
971980
examples/ci/ # the GitHub Actions workflow to copy
981+
examples/verify/ # render an imported page through ORDS as a temporary end user and inspect it
972982
docs/ # SPEC, risk model, CI/CD contract, import verification, auth design
973983
assets/brand/ # the FormsLang brand kit (SVG)
974984
```
@@ -1028,6 +1038,11 @@ CI runs the suite on Linux and Windows across Python 3.10–3.13, runs
10281038
- [x] Proof that a generated export imports on a real Oracle APEX 26.1
10291039
instance, and the repeatable render-time check
10301040
([`docs/apex-import-verification.md`](docs/apex-import-verification.md))
1041+
- [x] High-fidelity layout: the Forms geometry as native APEX components —
1042+
regions, sub-regions, tab pages, Interactive Grids for multi-record
1043+
blocks, native item types, template options — with a per-element
1044+
mapping report and the before/after of the showcase
1045+
([`docs/layout-mapping-matrix.md`](docs/layout-mapping-matrix.md))
10311046
- [x] Windows desktop app (bundled engine, MSI / NSIS installers)
10321047
- [x] Secure multi-user workspaces: RBAC, MFA/TOTP, per-organization
10331048
isolation — switched on from Settings or `FORMSLANG_AUTH`, the first

desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "formslang-desktop",
33
"private": true,
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"scripts": {
66
"tauri": "tauri",
77
"icon:render": "node scripts/render-icon.mjs",

desktop/src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "formslang-desktop"
3-
version = "1.0.0"
3+
version = "1.1.0"
44
description = "FormsLang desktop shell (B2DEV TECH)"
55
edition = "2021"
66
license = "Apache-2.0"

desktop/src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "FormsLang",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"identifier": "tech.b2dev.formslang",
66
"build": {
77
"frontendDist": "../ui-shell"

0 commit comments

Comments
 (0)