[LLV] Kanban demo server sync#641
Draft
mat-hek wants to merge 8 commits into
Draft
Conversation
98aa5f3 to
7e155be
Compare
6e30ef6 to
525d632
Compare
aa83a2e to
412674b
Compare
5cb8665 to
2d3d842
Compare
2d3d842 to
b06173a
Compare
mat-hek
commented
Jun 30, 2026
Comment on lines
+87
to
+96
| @doc false | ||
| # Top-level assign keys cross the JSON boundary as strings; convert them back to | ||
| # atoms so they read like Phoenix assigns (`@items`). Nested values are left as | ||
| # is — deeply atomizing arbitrary maps would be unsafe. | ||
| def __normalize_assigns__(assigns) do | ||
| Map.new(assigns, fn | ||
| {key, value} when is_atom(key) -> {key, value} | ||
| {key, value} when is_binary(key) -> {String.to_atom(key), value} | ||
| end) | ||
| end |
Contributor
Author
There was a problem hiding this comment.
Using JSON is quite inconvenient for client-server communication when both sides are in Elixir, and results in code like this. I think we should switch to erlang term format
Add a `@server` phx-target sentinel and a programmatic `push_server_event/3` so a popconent can deliver an event to the host (server) LiveView that mounted it, over the regular Phoenix websocket. The JS overrides the fake view's `withinTargets` to recognize the `@server` sentinel and resolve the host `[data-phx-session]` root fresh on each event (a reconnect can swap it out), dispatching via `liveSocket.owner`. A `window.__llvPushServer` hook backs the Elixir `push_server_event/3`.
Add a `@default` sentinel (dispatch locally, as if untargeted) and a
`LocalLiveView.targets/1` helper that joins several targets into one
`phx-target`, so a single interaction can be delivered to the popconent, the
host LiveView, and/or ordinary selectors/cids at once:
phx-target={targets([@default, @server])}
Tokens are joined with the ASCII Unit Separator (never present in a selector or
cid); the JS `withinTargets` override splits on it and dispatches each leg.
Adopt the new popconent in the example: convert the standalone `Local.KanbanLive` into a `Local.Kanban` popconent mounted by a server `BoardLive`, route "/" to it, and drop the default Phoenix page controller.
Rewrite the `Local.Kanban` popconent into an optimistic, collaborative client built on the new server-event APIs: edits apply locally and are pushed to the host via `push_server_event/3`, while removes ride `targets([@default, @server])` so the same DOM event runs both in the browser and on the server. Tasks carry client-generated fractional-index ranks (`Local.Rank`) with the task id baked in, so positions are globally unique and sort deterministically. The `OrderedMap` is gone — columns and tasks are plain maps sorted by position on render.
Back the demo with the database and make the server the source of truth.
* Schemas (Board/Column/Task) + migration, and a `Boards` context with the
edit operations (add/move/remove) that persist what the client generates.
* A board index LiveView plus a host `BoardLive` that applies each edit and
broadcasts `:board_changed` over PubSub, so every viewer re-reads and
reconciles (failures re-push the authoritative board to roll back).
* Seeds with fixed, counter-derived ids (stable across re-runs); inserts use
`on_conflict: :nothing` so re-seeding is idempotent.
ExUnit coverage for the `Boards` context and host `BoardLive`, plus a Playwright suite driving the WASM popconent end to end (board lifecycle, columns, tasks, drag & drop, two-client realtime, optimistic rollback). An `e2e_test.exs` boots the endpoint and runs the Playwright suite; the workspace/lockfile gain the `test/playwright` package.
GitHub Actions workflow that sets up Elixir + pnpm, installs Playwright browsers, and runs the local-lv-kanban ExUnit and e2e suites.
b06173a to
2a704af
Compare
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.
No description provided.