4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 624d6b846f |
feat(makepad-table): document library for Phase 3, and correct every stale note
Some checks failed
email.yml / feat(makepad-table): document library for Phase 3, and correct every stale note (push) Failing after 0s
repo hygiene / hygiene (push) Has been cancelled
makepad-table / model (push) Has been cancelled
makepad-table / widget (push) Has been cancelled
makepad-table / hygiene (push) Has been cancelled
Two things: the model layer Invoicer UI Phase 3 needs, and a sweep of the documentation, which was still describing the crate as it was six phases ago. `DocumentLibrary` in `makepad-doc-model` — open, save, recents and search, in the model rather than the app so it is testable without a window. The UI over it is not built; the README says so rather than claiming the phase. Three things it gets right that are easy to get wrong: - A document number becomes a filename and is user-controlled text. `safe_file_stem` replaces anything outside `[A-Za-z0-9._-]`, so `../../etc/passwd` cannot steer a write out of its directory. Leading dots go too, and a fully-stripped name falls back to `untitled`. - An empty query matches everything, so clearing the search box restores the list instead of emptying it. All terms must match, so each word narrows. - Recents de-duplicate and move to the front. Without that, re-opening one file fills the list with it and evicts everything else. doc-model tests 22 -> 31. Verified by reintroducing four defects: dropping the filename sanitising fails 3, removing the recents de-duplication fails 1, and switching the search from all-terms to any-term fails 2. The empty-query guard is honestly untested and marked as such below. Two test expectations I wrote were wrong and the code was right, which is worth recording because both look like search bugs and are not. Searching "globex" returns the invoice *and* the receipt — both are addressed to Globex, and finding every document for a client is the point. Searching "inv-2024-001" also returns both, because the receipt's line item reads "Invoice INV-2024-001 — Brand identity + website": it is the payment for that invoice, and surfacing it is the useful answer. Documentation, all of which had drifted: - `src/table.rs` called itself a "Phase 1 + 2 scaffold" with "Phase 3+ (SCAFFOLD ONLY — emits actions, no UI yet)". All six phases are implemented; the header now summarises what each one does. - `src/lib.rs` said Phase 3+ was "scaffolded via TableAction emissions but not yet implemented", and did not export the Phase 6 types at all. `parse_solid_spec`, `wireframe_edges`, `project_isometric`, `SolidSpec`, `SolidSpecError` and `Point3` were public but unreachable from the crate root. - `TableAction::RowMenuRequested` / `ColMenuRequested` were documented as "Phase 3 will open a PopupMenu". The widget opens the menu itself; these are notifications, not requests. - Both demos logged "Phase 3 will open PopupMenu" and neither handled `ColumnMoved`, so a Phase 4 drag produced no output in either. - The invoicer's header described a toolbar of six buttons that does not exist and a context menu as pending. - The README's caveats section listed three "if the compiler complains" predictions from before the crate had ever been built. All three are settled — `KeyCode::Tab` is right, `TextInput` needs no `ComponentRef`, pdf-writer 0.15 compiles as written — so it now lists the five real remaining limitations instead. - The README's workspace tree omitted `examples/table_demo` entirely and described `table.rs` as 1145 lines; it is 3260. The "drop into makepad" instructions were quietly wrong after Phase 5 and are now corrected with verified line numbers. They say to register `Table` next to `chart`, which at the pinned revision is line 611 — but `MathView` registers at 617, and `Table`'s DSL body names `mod.widgets.MathView`. Following the old advice literally would register the widget six lines before the type it depends on. |
|||
| c4b646c1fa |
feat(makepad-table): editable header, currency and tax, doc switcher (Invoicer UI Phase 2)
Some checks failed
email.yml / feat(makepad-table): editable header, currency and tax, doc switcher (Invoicer UI Phase 2) (push) Failing after 0s
repo hygiene / hygiene (push) Has been cancelled
makepad-table / model (push) Has been cancelled
makepad-table / widget (push) Has been cancelled
makepad-table / hygiene (push) Has been cancelled
The invoicer displayed the document number, issue date and due date in three `TextInput`s that were all `is_read_only: true`, because there was nowhere to write an edit back to. This is the write half, plus the currency and tax entry and the sidebar switcher the phase called for. Model (`makepad-doc-model`): - Setters for number, both dates, currency, default tax, issuer and recipient, each trimming its input. A trailing space in a document number becomes a trailing space in the exported filename, and a leading one makes two identical-looking documents sort apart. - `secondary_date`, `set_secondary_date` and `secondary_date_label`, because the second date is a due date on an invoice and a valid-until on a quote, and a receipt has neither. - `Currency::presets()` and `from_code()`. An unknown code is refused rather than turned into an `Other` with a guessed symbol and decimal count, which would format amounts confidently and wrongly. - `TaxRate::parse_percent`. - `switcher_label()`. **A defect this uncovered.** `Document::default_tax()` returned `None` for a receipt, even though `Receipt` carries a `default_tax` field like the other two and its `tax_total_minor()` bills from it. The accessor was the only thing claiming a receipt has no default rate. `document_to_table_data` trusted it, substituted `TaxRate::zero()`, and printed 0% in the Tax column for every un-overridden line while the totals underneath were computed from the real rate — the table and the total disagreeing on the same screen. It never showed because the shipped sample receipt is 0%-rated, so the wrong answer and the right one coincided. It separates as soon as a rate is set, which is exactly what the tax field added here now lets a user do. Fixed at the accessor, so the table builder is corrected without touching it. **A second one.** `TaxRate::percent` casts `f64 -> u32`, and that cast saturates: `percent(-5.0, ..)` is 0%, and so is `percent(f64::NAN, ..)`. Neither refuses, so a user typing nonsense into the new field would have got a plausible-looking rate they did not ask for. `parse_percent` validates first — finite, 0 to 100 — and returns `None` otherwise. Rejected input is reported in the status line and the field is reset to the stored value, so the box never keeps text the document did not accept. UI: - The three header inputs are editable, with a white background and a focus border rather than the read-only grey. - The due-date field used to render "2024-05-01 (valid until)" for a quote — the label baked into the value, so it could not be edited without deleting the annotation. The label is now on the label. - Currency and default-tax fields. - Three sidebar buttons switch document, labelled from the documents themselves, with the current one named below. - Header edits commit on Return or focus loss, not per keystroke: re-reading the model on each character fights the caret, and a half-typed date is not a date. Also fixed, all pre-existing: - `examples/table_demo` did not compile. It used `action.cast::<T>()`, which makepad's Action API no longer has. That package was in no workspace and had no CI until the previous commits, so it never failed loudly — it was simply never built. This is the second defect found purely by putting it somewhere a compiler would look. - Both demos imported `makepad_widgets` alongside `makepad_table`, which re-exports it wholesale, making every widget name ambiguous. - A dead `refresh_totals_display` no-op stub. - Stale "Phase 3 will open PopupMenu" status strings; the menus exist. doc-model tests 12 -> 22, and all five crates now pass `clippy --all-targets -D warnings`. Verified by reintroducing three defects: restoring `None` for a receipt's default tax fails the tax-reporting test, letting `parse_percent` fall through to `percent` fails the validation test, and dropping the trim fails the whitespace test. Invoicer UI Phase 3 (file browser, recent documents, search) remains open. |
|||
| ea98d4d95c |
fix(makepad-table): exclude from the workspace, pin makepad, fix money defects
Some checks failed
nigig-build (CAD) / supply-chain (push) Has been cancelled
nigig-build (CAD) / cad-module (push) Has been cancelled
nigig-build (CAD) / full-crate-check (push) Has been cancelled
nigig-build (CAD) / cad-engine-coverage (push) Has been cancelled
repo hygiene / hygiene (push) Has been cancelled
email.yml / fix(makepad-table): exclude from the workspace, pin makepad, fix money defects (push) Failing after 0s
doc-engine / engine (push) Has been cancelled
doc-engine / consumer (push) Has been cancelled
nigig-map / test (push) Has been cancelled
sms / gates (push) Has been cancelled
sms / robius-sms (push) Has been cancelled
sms / android (push) Has been cancelled
sms / nigig-sms (push) Has been cancelled
sms / supply-chain (push) Has been cancelled
`crates/apps/makepad_table` is a nested workspace that has never been compiled — its README says as much: "written without a local cargo/rust toolchain, so the first compile on your machine is the verification step." This is that step. Four crates, all of which build, and three defects in the money code that only a compiler and a test runner could have found. Workspace containment, which is what was asked for: - The root manifest now names `crates/apps/makepad_table` in `exclude`. Cargo already declined to absorb it, because the crate carries its own `[workspace]` table — but that made the isolation a property of someone else's manifest. Deleting that table would have pulled four crates and a second makepad checkout into every workspace-wide build. Verified: the root workspace resolves 58 members and none of them are these. - `examples/table_demo` belonged to no workspace at all and had no `[workspace]` table of its own, so `cargo metadata` failed outright in that directory. It is now a member of the nested workspace. Kept rather than deleted: it is the template the README's "drop into makepad" section refers to. - All three manifests pinned to the fork revision the rest of the repo uses (`gitdab.com/andodeki/makepad` @ ecf5a57) instead of tracking `github.com/makepad/makepad` branch `dev`. A floating branch means the same commit of this repo builds against a different makepad from one day to the next, and against a different makepad from every other crate here. All four crates verified to compile against the pin. The defects, in the order they surfaced — each was hidden by the one before it: 1. `format_with_thousands` computed `(i - first_group_len)` before the `i >= first_group_len` guard that protects it. `&&` short-circuits left to right, so the check never ran in time. Any number whose leading group is short of three digits — 2, 3, 5, 6, 8, 9, 11, 12 digits wide — underflowed a usize: a panic in debug, silent wrapping and misplaced commas in release. Every currency string in the application went through it. The two existing tests used 1234 and 1234567, the two widths that happen to work. 2. With the panic gone, `Currency::format` was visibly wrong on negatives. The symbol was emitted before a signed whole part, giving "$-12.34" instead of "-$12.34"; and `whole` truncated toward zero while `frac` used `rem_euclid`, so the two disagreed below zero. -1234 formatted as "$-12.66" and -1 as "$0.99" — the wrong sign, the wrong place, and the wrong amount. 3. `invoice_totals_arithmetic` asserted `1_840_00` where the sample data totals 1_840_000 minor units. The prose in the same comment said 18,400.00, which is right; the literals were a factor of ten low. The arithmetic was never wrong, the expectations were. The two loose range assertions on tax and grand total are now exact equalities. Tests 12 -> 16 across the two crates, and all 16 pass; previously 6 of 12 failed. Each fix was verified by reintroducing the defect on its own: the guard-order bug fails 5 tests, the sign bug fails 4 with the overflow fix left in place, and dropping the per-line discount from the tax calculation fails the arithmetic test by 71.32 — an error the old range assertions were wide enough to have accepted. |
|||
| 258fa3259e | Merge origin/main: resolve xref/document conflicts, add makepad_table |