feat(materialize): the Create-from preview / edit / confirm window (#15) - #114
Merged
Merged
Conversation
Builds the finalization window that opens once a destination is chosen and shows exactly what will be created, before anything is saved. It lives in `:core:materialize` on top of #11's domain so the five entry points share one window instead of re-implementing the preview and the confirm discipline; the Compose plugin is enabled on the module for it. - The destination is switchable from inside the window (List / Doc / Both / Message). Nothing is discarded on a switch: the edits stay in state and `toRequest()` is the single place that decides which of them a destination can carry, so a title survives List → Doc while columns, which a document has no use for, simply do not reach the request — and are still there on the way back. - For a list: title, optional description, column rename / retype / remove / Add column over the twelve-value `ListColumnType`, public-private, and a live table of the rows and columns. A blank title is refused locally because the server answers `A list title is required`. - For a document: title, file name, public/private, numbered or bulleted list style, inline or sub-item row data, with a rendered markdown preview built from the *source* columns — `docConfig` carries no field list, so previewing renamed list columns would promise something the request does not ask for. - On success both navigation targets are exposed independently, so a `both` conversion offers a link into the new list and into the new document. - The subscriber gate is consumed, not re-implemented: a free account's confirm is refused by the repository before a byte leaves the device and surfaces as `subscriptionRequired` for the host's existing upsell handling. Message → message stays hidden, as the help centre documents (Quote or Push covers it), and the message destination creates nothing: it hands the composer the draft the server built. Tests: 21 new unit tests — column edits reaching the create request, the destination switch preserving what still applies and dropping what cannot, both navigation targets on success, a blank title refused with no request, a free account confirming with a real socket that never sees a byte, and the document renderer's four styles. Plus a Compose UI test for the window. `./gradlew :app:assembleDebug testDebugUnitTest` is green (65 tests in `:core:materialize`, 0 failures). Closes #15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #15. Part of epic #10. All five entry points (#12, #13, #14, #16) open this one window.
Built in
:core:materializeon top of #11's domain. Nothing outsidecore/materialize/was touched.Design
target; nothing isthrown away.
MaterializeWindowUiState.toRequest()is the single place deciding which edits adestination can carry — so a title survives List → Doc (it still applies), while column edits do
not reach a doc request (a document has no columns) yet are still there on the way back.
MaterializeLaunch(source, initialTarget, preview).MaterializePreviewis neutral display material — suggested title/description/file name,MaterializeColumns, preview rows keyed bypropertyKey,totalRowCount,defaultIsPublic. Thewindow never reaches into a feature module, and only column schema ever leaves the device,
consistent with Create from…:
POST /api/materializeplumbing + domain model #11's id-only source rule.bothexample gives list and document the same title, and it makes a destination switch preserve them
for free.
docConfigcarries no field list, so showing renamed columns would promise something the requestdoes not actually ask for.
message destination creates nothing and hands back the server-built draft — that is Create from…: "To Message" prefills the composer instead of creating #16's hook.
POST /api/materializeplumbing + domain model #11's repository refuses a free accountbefore the request goes out, surfacing as
subscriptionRequired.Verification
./gradlew :app:assembleDebug testDebugUnitTest→ BUILD SUCCESSFUL.:core:materialize65 tests,0 failures (21 new), covering all four required cases:
sourceKeyand a derivedpropertyKey;Doc→List, →Message);
7 Compose UI tests compile, not executed (no emulator).
core/materialize/build.gradle.ktsgains the Compose plugin and deps — as #11 anticipated, so thewindow lives in one place instead of five.
Note for #12–#14
The window can only preview what the entry point seeds, so each entry point must supply correct
sourceKeys. For a messages source the documented defaults are Content / Author / Posted / Links /Tags, but the wire spellings are not published, so they were not guessed here. An entry point
that seeds no columns simply sends no
fieldsand lets the server derive them — a safe default.