Uh oh!
There was an error while loading. Please reload this page.
Updates to media browser - #544
Merged
Merged
Conversation
Two bugs were collaborating. `Storage.folder_breadcrumbs/2` returns the full ancestor chain INCLUDING the target folder (scope dropped when scoped), but the heex iterated `@breadcrumbs` as links AND appended `@current_folder.name` separately — duplicating the last entry. And the leading "root" button hardcoded "All Media" even when the browser was constrained to a scope, hiding the scope folder's name entirely. For a MediaBrowser scoped to `banana` viewing folder `wendalina`, the old render was `All Media > wendalina > wendalina`. Now it correctly shows `banana > wendalina`. - Iterate `Enum.drop(@breadcrumbs, -1)` for the clickable middle ancestors, render the current folder once at the trailing `<li>`. - Leading button reads `@scope_folder_name` when `@scope_folder_id` is set, falling back to `gettext("All Media")` otherwise. The `:scope_folder_name` assign is already computed in `init_socket`, it just wasn't being read. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files in both grid and list views now carry the same `...` overflow menu folders have — Download (when an "original" URL is present) and Delete. Closes the long-standing gap where the only way to delete a single file was to enter select mode, tick it, and hit the toolbar trash. - Grid view: kebab fades in at top-right on hover, sibling of the click target so its buttons don't trigger `click_file`. - List view: kebab in the trailing `w-10` column reserved in the thead but previously empty. Wrapped in `phx-click="noop"` to swallow the bubble before it hits the row's `click_file`, mirroring the folder list-view kebab. - Both menus hidden in `@select_mode` (the row is a selection target in that state). - Delete label flips with `@filter_trash`: "Move to Trash" outside (no confirm — reversible), "Delete Permanently" inside trash (with `data-confirm` showing the filename). - `onclick="this.blur()"` on each menu button releases the `:focus-within` daisyUI uses to keep the dropdown open, so the menu collapses immediately after a click. Runs alongside `phx-click` without conflict. New `media_browser.ex` handlers: - `delete_file` — single-file scope-guarded delete that mirrors `delete_selected`'s trash-vs-permanent branching. - `download_file` — pushes a one-entry `download_files` event (same JS hook the bulk download uses). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four related changes that converge folder and file rows in list view toward visual parity, plus a new single-item Move flow available from both kebabs. - **Column alignment.** Folder list rows previously had a stray empty `<td>` between the name (colspan=5) and the kebab, pushing the kebab into a phantom 9th column past the thead. Removed it so the folder kebab now lands in the actions column directly above the file kebab. - **Type + Date for folders.** Replaced the folder name's colspan=5 with discrete cells so the Type and Date columns now render — "Folder" badge (matching the file type badge style) and `folder.inserted_at` (same strftime format as file rows). - **Path for folders.** New private `folder_parent_path/1` helper mirrors how `enrich_files` builds `folder_path` for files (`Storage.folder_breadcrumbs/1` joined with " / "). Folder rows now show their parent path in the Path column, matching the file pattern (`/` placeholder at root). - **Move action in kebabs.** New `prepare_move_file` / `prepare_move_folder` handlers seed `selected_files` / `selected_folders` with a single-item set and open the existing move-target modal, reusing `move_selected_to_folder` without touching select_mode. `close_move_modal` now clears those sets when not in bulk select mode so a cancelled kebab move doesn't leave a stale single-item selection behind. Modal title generalised from "Move N file(s)" to "Move N item(s)" so it reads correctly for files, folders, and mixed selections. Added to all four kebab spots (file grid, file list, folder grid, folder list) with `hero-folder-arrow-down` icon, between Download/Color and Delete. `onclick="this.blur()"` on each new button closes the dropdown before the modal opens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In a scoped MediaBrowser, the move modal's "root" button sent `phx-value-folder_uuid=""`, which both move handlers converted to `target = nil`. For files, `move_file_to_folder/3` then rejected `within_scope?(nil, scope_folder_id)` and returned `:out_of_scope`, silently failing the move. For folders, the scoped `update_folder/3` clause skips the parent-scope check when `new_parent` is nil, so the folder *would* move — but to the system's true root, escaping the scope entirely. Both reachable from the per-item kebab Move flow and the bulk-select Move toolbar action; the same pattern also applies to the drag-drop `move_file_to_folder` handler. Both handlers now resolve "" → `scope` (the scope folder's uuid) before calling Storage. Unscoped browsers are unchanged because `scope` is nil there. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Defence-in-depth follow-up to 77d84e6. The scoped `update_folder/3` clause used `new_parent && not within_scope?(...)` to gate the scope check — short-circuiting when `new_parent` was nil. That let a caller silently reparent a scoped folder to the system root by passing `%{parent_uuid: nil}`, escaping its virtual scope. The MediaBrowser caller no longer hits this path (77d84e6 resolves empty → scope at the handler level), but `Storage.update_folder/3` is public and could be called by any future consumer, so the storage layer should enforce the invariant itself. Now uses `Map.has_key?` to distinguish "attrs omits parent_uuid" (rename/recolor — no move attempted) from "attrs has parent_uuid: nil" (an explicit move to the system root). Any explicit `parent_uuid` in attrs runs the scope check, and `within_scope?(nil, scope)` is false when scope is set, so move-to-true-root attempts now correctly fail with `:out_of_scope`. Added a regression test covering both atom and string keys, since the scope_test suite is the canonical surface for this invariant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small cleanups from /simplify review of the MediaBrowser
session changes:
- Replaced `folder_parent_path/1` (called per row in the folder list)
with a single `folder_list_path/2` precomputed once in heex. All
displayed folders share the same parent, so the previous helper did
N identical breadcrumb walks per render. With `folder_list_path/2`
it's one walk; ~3-10x query reduction on typical folder lists.
- Extracted `breadcrumb_path/1` private helper for the
`Storage.folder_breadcrumbs |> Enum.map_join(" / ", & &1.name)`
pattern. Used by both `enrich_files` (per-file Path) and the new
`folder_list_path` (per-render folder list Path). Single point of
change for the path-string format.
- Documented the `parent_uuid: nil` vs omit-key contract on
`Storage.update_folder/3`. Non-obvious Elixir idiom that the
scope tightening in 376737f depends on.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>**Feature.** Files can now be dragged onto the sidebar Trash button to soft-delete them. Reuses the existing `MediaDragDrop` JS hook's dataTransfer pipeline — new `[data-drop-trash]` block mirrors the existing `[data-drop-folder]` wiring, with error-colored hover feedback (`ring-error`, `bg-error/10`) to make the destructive action read as different from a folder move. New `trash_file` server event handler scope-guards via `Storage.within_scope?/2` and always calls `Storage.trash_file/1` (drag-to-trash is "put in trash", not "permanently delete" — permanent deletion stays explicit via the kebab or Empty Trash button). **Crash fix.** `load_trashed_files` and `load_orphaned_files` were hand-rolling the per-file display map and omitted `:folder_path` entirely. The list-view template at media_browser.html.heex:1310 reads `file.folder_path` unconditionally, so opening Trash or Orphans in list mode crashed with `KeyError`. Pre-existing latent bug; surfaced by drag-to-trash because before this feature the trash view often had no rows in the test setup. Both loaders now delegate to `enrich_files/1` for the per-file shape (`urls`, `folder_path`, `variant_widths`, etc.). ~78 lines of duplicated map construction removed. The unused `:trashed_at` field the trash loader added is gone — verified nothing in the heex reads it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the user toggled into the trash view, the sidebar continued to highlight whichever folder, the Root entry, or the All Files entry they came from — visually it read as "in trash AND in some folder", two active selections at once. The internal `@current_folder` / `@file_view` state is intentionally kept so toggling trash back off restores the previous view, but the sidebar highlight is now gated on `not @filter_trash`. In trash view only the Trash button carries the active highlight; flipping trash off restores the previous folder/root/all-files highlight. Threaded `filter_trash` through `folder_tree_node` (recursive component) so `:is_active` accounts for trash mode, and added the same `and not @filter_trash` guard to the All Files and Root buttons in the sidebar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Folders are now drag sources alongside files. Drag any folder from
grid, list, or sidebar onto any other folder (in grid, list, or
sidebar) — full four-way drop matrix. The drop targets pre-existed;
this adds the source-side wiring and the backend handler.
**Drag protocol.** Folder drags carry the uuid in `text/plain` (same
as files) plus a marker `application/x-pk-folder` type so drop
targets can branch on folder-vs-file at dragover time without
parsing the payload (dataTransfer values aren't readable on
dragover, only types are). The source uuid is stashed on
`self._draggedFolderUuid` for self-drop suppression.
**Self / cycle protection.** JS suppresses the drop indicator when
hovering the source folder onto itself. Drop-on-descendant still
slips through (tree topology isn't reachable from JS) but the server
rejects with `{:error, :cycle}` and surfaces a flash.
**Trash drop refuses folders.** Folders don't trash (no soft-delete
for folders), so the trash drop target rejects folder drags at both
dragover and drop — user sees a no-drop cursor instead of a
misleading red ring.
**Folder mutations now refresh `@folders` + `@folder_tree`.** Added
`reload_folder_lists/1` helper alongside `reload_current_page/1` and
wired it into the three handlers that mutate folder rows:
`move_folder_to_folder` (new), `move_selected_to_folder` (bulk
move), and `delete_selected` (bulk delete). Without it the UI showed
the moved/deleted folder in its old position until a manual page
refresh. The existing single-folder mutators (`delete_folder`,
`rename_folder`, `change_folder_color`) already refreshed inline.
**Drop indicator visual fixes.**
- Grid / list folder cards carry an inline
`style="background-color: ..."` from `folder_bg_style` which beat
any class-based bg. Stash + clear the inline so `bg-primary/10`
can take effect, restore on dragleave / drop.
- `<tr>` (list-view row) doesn't render `box-shadow` reliably, so
switched from Tailwind's `ring-*` to inline CSS `outline` —
works on any element type and respects border-radius in modern
browsers.
- Used daisyUI 5's `var(--color-primary)` directly. The legacy
`oklch(var(--p))` form (still present in some heex files) is from
daisyUI 4 where `--p` was raw oklch components; daisyUI 5 ships
the full oklch() in `--color-primary` so no wrapping needed.
- `outlineOffset: -2px` insets the outline so the table's
`overflow-x-auto` wrapper can't clip the left/right edges of
list-view rows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Dropping a folder or file onto the body of MediaBrowser (empty space
or anywhere outside a specific folder card) now moves the item into
the currently-viewed folder. Visual is a single blue outline around
the entire body region — matches the user's screenshot. Nested drop
targets behave exclusively: only the innermost target highlights at
any time.
**Heex** — new `<div class="rounded-lg" data-drop-folder={...}
data-drop-no-bg>` wrapping the empty-state / grid / list block. The
`data-drop-folder` expression resolves to `@current_folder.uuid` /
`"root"`, or `nil` in trash and all-files views (where dropping into
"current folder" doesn't make sense). The formatter re-indented the
wrapped content — large diff, small logical change.
**JS** —
- New `data-drop-no-bg` opt-out gate on the bg fill in
dragover/dragleave/drop. The 10% primary tint on folder cards is
great; on a whole content-area wrapper it'd be overwhelming.
- New `self._activeDropTarget` tracker for exclusivity between
nested targets (wrapper + folder card). When dragover fires on a
new target, the previous active is cleared first. dragleave / drop
release the tracker; file + folder dragend also clear it so a
cancelled drag (Esc, drop outside) doesn't leave a lingering
highlight.
- Extracted `clearHighlight(t)` helper inside `setupDragDrop` so the
same teardown happens consistently from dragleave, drop, and
dragend, and honours `data-drop-no-bg`.
No backend changes — `move_file_to_folder` / `move_folder_to_folder`
already accept any folder uuid as target (including the current
one). A drop onto the body where the item's already in that folder
is a no-op `update_folder` server-side, no flash anomaly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Picking up any item that's part of the current select-mode selection
now drags the *whole selection* — drop anywhere (folder card,
sidebar, main wrapper) and every selected file/folder moves
together. Picking up unselected items still single-drags as before.
Visual feedback: every selected item grays out (opacity-50) on
dragstart so it's obvious what's coming along, not just the one
under the cursor. Restored on dragend.
**Server-side change**: none. The drop fires the existing
`move_selected_to_folder` event, which already iterates
`@selected_files` + `@selected_folders`, scope-resolves the target,
skips drop-on-self for folders, and clears select state + refreshes
folder lists / current page. The bulk move modal has been firing
this for a while — drag-drop is just a new trigger.
**Heex** — `data-selected={if @select_mode && MapSet.member?(...,
uuid), do: "true"}` added to all four draggable element sites
(grid file, grid folder, list file, list folder).
**JS — `setupDragDrop`**
- New `setBatchVisuals(active)` helper toggles `opacity-50` on every
`[data-selected="true"]` element. Single query covers all four
rendering paths.
- File + folder dragstart: if the source element carries
`data-selected="true"`, set the `application/x-pk-batch` marker
type, flag `self._draggedBatch = true`, and call
`setBatchVisuals(true)`. Otherwise the existing single-item path
(only the dragged element grays out).
- File + folder dragend: if `_draggedBatch`, clear batch visuals and
reset the flag; otherwise the existing single-item path.
- Drop handler branches on the batch marker FIRST. Batch → push
`move_selected_to_folder` with just `{folder_uuid: resolvedTarget}`.
Otherwise the existing single-item branching by folder vs file.
- Trash drop refuses batch drags at both dragover and drop — the
batch may include folders (no soft-trash) and bulk-trash-via-drag
conflates move and destroy. Users wanting bulk trash use the
toolbar delete button.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Symptom: in views with few items, the kebab dropdown was clipped by the parent card's `overflow-hidden` (daisyUI's `.card` wrapper hides overflow for rounded corners). User reported only "Download" was visible — the rest of the menu vanished below the card boundary. Root cause: daisyUI's `dropdown-content` uses `position: absolute`, so it's confined to the parent stacking context. Any ancestor with `overflow: hidden` clips it. Fix: refactor all four kebabs (folder grid, file grid, folder list, file list) from daisyUI's inline `dropdown` to the existing `<.table_row_menu>` component, which uses `phx-hook="RowMenu"` to position the menu with `position: fixed; z-[9999]`. That escapes every `overflow-hidden` ancestor — including the daisyUI parent card the user hits in kit_test. The hook also auto-flips the menu above the trigger when there's no viewport space below. **Side fixes that come for free:** - `onclick="this.blur()"` dropped from every menu item — the hook closes via `_onMenuClick` after any item click. - `phx-click="noop"` wrappers dropped from list-view kebabs — the hook's trigger handler calls `stopPropagation` directly so clicks don't bubble to the row's `click_file`. - Esc + arrow-key navigation now work in the menu (RowMenu hook features that the daisyUI dropdown didn't have). **Side fix to TableRowMenu**: added optional `trigger_class` attr so callers can customize the trigger button. The file grid kebab uses it to preserve its dark overlay (`!bg-black/40 ...`) needed for visibility against thumbnails. **Folder color picker** stays as inline `<li role="none">` content inside `<.table_row_menu>` — it's a custom UI (color circles row) that doesn't fit `<.table_row_menu_button>`. The slot accepts any HTML so this works cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two features bundled — they touch overlapping handlers and the trash work supersedes some of the untitled-folder paths. ## Instant folder creation Replaces the inline-input "New Folder" UX with Finder/Explorer-style instant creation. Clicking "+" creates a folder named `untitled` (or `untitled 1`, `untitled 2`, ... if conflicts) immediately, no prompt. User renames via the kebab → Rename action afterward. - New `create_untitled_folder` event handler + `next_untitled_name/2` helper. Helper walks existing siblings, picks the first available name — gaps fill before extending (if `untitled` and `untitled 5` exist, picks `untitled 1`). - Guards `filter_trash` and `file_view == "all"` with explanatory flash errors. - Removes the old `toggle_new_folder` / `create_folder` event handlers and all three inline-input UI blocks (sidebar root, grid, list, plus the tree-node child input). `@show_new_folder` assign + the same-named `folder_tree_node` attr are gone. ## Folder trash (recursive) User asked for "move a folder or selected folders to the trash and their contents." Folder soft-delete didn't exist before — folders were always permanently destroyed with reparenting. Now they get the same trash/restore/permanent-delete cycle files have had since V99. ### Migration V119 Adds `trashed_at TIMESTAMPTZ` to `phoenix_kit_media_folders` with a partial index on `trashed_at IS NOT NULL` for fast trash-view queries. All idempotent. Bumps `@current_version` 118 → 119. ### Schema + storage - `Folder` schema gets the `trashed_at` field + cast permission. - `Storage.trash_folder/2(folder, scope)` — recursive soft-trash via `folder_subtree_uuids/1` (breadth-first walk). Marks the folder + every descendant as trashed and stamps `status: "trashed", trashed_at: now` on every file in the subtree. Scope-guarded. - `Storage.restore_folder/2` — reverses the trash, recursively. - `Storage.delete_folder_completely/2` — hard-deletes the subtree bottom-up (leaves first so FKs stay happy), routing files through `delete_file_completely/1` so storage-backend cleanup runs. - `Storage.list_trashed_folders/2`, `count_trashed_folders/1` — for the trash view + sidebar badge. - `list_folders/2`, `list_folder_tree/1`, `list_all_folders/0` now filter `is_nil(trashed_at)`, hiding trashed folders from every non-trash view without explicit caller changes. ### Event handlers - `delete_folder` event: branches on `filter_trash` — soft-trash outside the trash view, recursive permanent delete inside. Mirrors the file behavior. - `delete_selected`: folders now soft-trash too (outside trash) / recursive permanent delete (inside). The CLAUDE.md "no trash for folders" comment is obsoleted. - `restore_selected`: extended to handle folders alongside files. - New `trash_folder` event handler for drag-to-trash on a single folder. Always soft-deletes regardless of view. - `toggle_trash_filter`: populates `@folders` with `list_trashed_folders/2` when entering the trash view, so trashed folders render as rows alongside trashed files. - `reload_folder_lists/1` mirrors that branch. - New `full_trash_count/1` helper (files + folders) used in the four spots that assign `@trash_count`. Sidebar badge now reflects the whole trash bucket. ### JS `MediaDragDrop`'s trash drop target previously rejected folder and batch drags. Now both are accepted: - Single folder → push `trash_folder` (new event). - Single file → push `trash_file` (existing). - Batch → push `delete_selected` (existing; reads `@selected_files` + `@selected_folders` + branches on `@filter_trash` server-side). ### Side fix `Storage.other_files_share_path?/1` blew up on files with `nil` `file_path` (Ecto forbids `column == nil`). Surfaced by the new `delete_folder_completely` test; fixed by short-circuiting on nil. ### Tests `test/integration/storage/scope_test.exs` gains four describe blocks covering `trash_folder`, `restore_folder`, and `delete_folder_completely`. Recursive subtree behavior, scope guards, and effects on `list_folders` / `list_folder_tree` / `list_trashed_folders` are all asserted. 53/53 pass. ## Deferred - Single-folder kebab "Restore" — restore is bulk-only via select-mode in the trash view today. Folder kebab in trash view still shows Rename / Color / Move; weird but harmless. Tightening to "Restore + Delete Permanently only" is a separate UI pass. - Trashed folders are clickable in trash view (could navigate into a trashed folder via the inner button). Edge case; haven't seen reports yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two UX changes to the sidebar tree's inline rename: - Input swapped from the previous transparent `bg-transparent border-none outline-none ...` styling (visually indistinguishable from plain text) to a thin primary-bordered field on a white bg. Sits flush with the row's natural height — keeps the folder icon and tree indentation proportionate while reading clearly as "editable". Tried daisyUI's `input input-bordered input-xs` first but the chunkier border + larger height made the row layout look squished; the minimal `border border-primary/60 rounded px-1.5 py-0` reads cleaner. - `phx-blur="cancel_rename_folder"` on the input — clicking anywhere outside the input now cancels the rename, alongside the existing Esc keybind. The `cancel_rename_folder` handler clears state idempotently, so a blur after Enter-submit (when the input is removed from DOM) is a harmless no-op against already-cleared state. Also tried a row-wide `ring-2 ring-primary` to flag the rename mode visually but the user found it too noisy — the input border alone is enough signal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Folder icons in the main content area were noticeably small compared to file thumbnails — folders read as a second-class element. Bumping them to match. - Grid view folder card: w-12 → w-20 (48px → 80px). Roughly half the typical ~150px aspect-square card; folder name still has room below. - List view folder row (icon in a w-10 h-10 wrapper): w-6 → w-10 (24px → 40px). Fills the wrapper now, matching the file thumbnail size so folders and files line up cleanly in the same column. Each appears twice per view (normal display + inline-rename branch), both bumped together. Sidebar tree icons stay at w-4 h-4 — tree nav is intentionally tight and bigger icons there would break the indentation grid. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The folder tree sidebar (toolbar + All Files / Root / Trash buttons + inline rename) is now its own function component so other LiveViews can embed folder navigation without duplicating ~170 lines of markup. MediaBrowser becomes the first consumer; events stay wired through @Myself so all 13 handle_event clauses remain unchanged. Color helpers (folder_color_hex/1, folder_icon_style/2, folder_bg_style/1) move with the component since the grid/list folder cards consume them too — MediaBrowser imports them back from FolderExplorer. Adds three reuse flags (show_create, show_all_files, show_trash, all default true) so folder-picker consumers can drop MediaBrowser-specific buttons without forking the markup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump child UL pl-1 → pl-1.5 so each nested level's chevron sits at the parent's folder-icon x-position. The connecting line stays at the parent chevron tip (ml-3 unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps fresco CDN to v0.1.5 and uses its new `theme={:inherit}` mode
on the MediaBrowser zoom viewer. Inherit mode opts the viewer out of
Fresco's own --fresco-* declarations; phoenix_kit supplies the
mapping to daisyUI tokens (base-100 / base-200 / base-300 /
base-content / primary) so background, dot grid, and nav buttons
follow whichever daisyUI theme is active on <html> — light gray
chips on light themes, dark gray on dark.
The mapping is shipped via two paths so it works in every parent
app: in phoenix_kit's own app.css for standalone pages, and injected
at runtime from phoenix_kit.js for parent apps (kit_test) that
serve their own compiled CSS and don't load phoenix_kit's app.css.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Exposes etcher 0.2.5's new dimension tool (line with arrows on both ends + slidable label) in the MediaBrowser viewer's annotation toolbar. Server-side bookkeeping to accept the new kind: - PhoenixKit.Annotations.Annotation: 'dimension' added to @kinds so the changeset's validate_inclusion accepts it. - V119 migration: widen phoenix_kit_annotations_kind_check to include 'dimension'. Folded into the existing V119 (folder trash) since neither has shipped to a tagged release yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Picks up etcher's new dimension annotation (line + arrows + slidable label) and the cross-browser baseline fixes in v0.2.4 / v0.2.5. Also refreshes the comment that documents the matching hex requirement. mix.exs stays at `~> 0.2` for now since 0.2.5 isn't published yet — will tighten to `~> 0.2.5` once published. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
phoenix_kit now relies on features only in fresco 0.1.5 (theme: :inherit) and etcher 0.2.5 (dimension annotation, callout/text/dimension in the schema's @kinds). Bumps the requirements from `~> 0.1` / `~> 0.2` to `~> 0.1.5` / `~> 0.2.5` so the resolver enforces the floor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Picks up the dimension-creation flow fix: dimension shapes no longer auto-open an inline label editor that was blocking the composer popup. The composer now handles label + comment in one flow, so clicking an existing dimension in cursor mode highlights its linked comment via the existing data-annotation-uuid chain. mix.exs req still at `~> 0.2.5` until 0.2.6 lands on hex. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Picks up the dimension-creation flow fix (no auto-inline-editor on creation) on the resolver side. The CDN URL was already bumped in the prior commit; this just enforces the floor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # mix.lock
ddon pushed a commit
that referenced
this pull request
May 15, 2026
ddon pushed a commit
that referenced
this pull request
May 18, 2026
Complete the 1.7.112 entry to cover all unreleased work since v1.7.111: PR #548 (table_default sort/DnD, bulk_actions_bar, empty_state, sort_selector, form_section/form_actions, Reorder/Values/Format utils), PR #544 (MediaBrowser folder management overhaul), PR #545 (V120 document-creator taxonomy), PR #547/#542 (i18n manifests), and this session's post-merge cleanup. Re-dated to 2026-05-18. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 freeto 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.