+ Builds the field below automatically. If your pattern is more complex than this covers, just edit it directly below - these controls won't touch it unless you use them.
+
"
+ );
+ found = true;
+ });
+ }
+
+ return found;
+ }
+ });
+ }
+};
+
menu_items = {
initialize_search : function() {
initSearchPicker({
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css
index da31535..ade3a62 100644
--- a/public/stylesheets/admin.css
+++ b/public/stylesheets/admin.css
@@ -1052,6 +1052,16 @@ div#draft_list table td.actions a {
border-bottom: none;
}
+.search_results p.search_group_label {
+ margin: 8px 0 2px;
+ padding: 0;
+ border-bottom: none;
+ font-size: 0.75rem;
+ color: #969696;
+ text-transform: lowercase;
+ font-weight: normal;
+}
+
/* ============================================================
Menu items (navigation editor)
============================================================ */
diff --git a/test/controllers/admin_controller_test.rb b/test/controllers/admin_controller_test.rb
index 13cc1bb..9beaf58 100644
--- a/test/controllers/admin_controller_test.rb
+++ b/test/controllers/admin_controller_test.rb
@@ -34,4 +34,28 @@ class AdminControllerTest < ActionController::TestCase
matches = assigns(:mynodes).select { |n| n.id == node.id }
assert_equal 1, matches.length
end
+
+ test "dashboard_search returns matching tags and nodes grouped separately" do
+ node = Node.root.children.create!(:slug => "dashboard_search_test")
+ node.find_or_create_draft(User.find_by_login("aaron"))
+ node.draft.update(:title => "Biometrics Workshop")
+ node.draft.tag_list = "biometrics-workshop"
+ node.draft.save!
+
+ login_as :quentin
+ get :dashboard_search, params: { :search_term => "biometr" }, :format => :json
+
+ json = JSON.parse(response.body)
+ assert json["tags"].any? { |t| t["name"] == "biometrics-workshop" }
+ assert json["nodes"].any? { |n| n["title"] == "Biometrics Workshop" }
+ end
+
+ test "dashboard_search returns empty results for a blank term" do
+ login_as :quentin
+ get :dashboard_search, params: { :search_term => "" }, :format => :json
+
+ json = JSON.parse(response.body)
+ assert_equal [], json["tags"]
+ assert_equal [], json["nodes"]
+ end
end
--
cgit v1.3
From 8baac265059b70da0148487458ee4077b15f155e Mon Sep 17 00:00:00 2001
From: erdgeist
Date: Mon, 13 Jul 2026 04:54:33 +0200
Subject: Asset picker: attach/detach/reorder UI, read-only view, autosave fix
Replaces nodes#edit's old Images section -- a hidden panel dumping
every image asset in the system unfiltered (#image_browser) plus a
raw drag-and-drop box (#image_box) -- with a small search-and-click
picker built on the endpoint from the last two commits. Attaching
posts immediately and appends the new thumbnail via a cloned
-- icons only render correctly through the Rails helper
server-side, so the template holds real, pre-rendered markup for JS
to clone rather than duplicating raw SVG in a JS string. Reordering is
jQuery UI sortable on the small attached list only, with a dedicated
drag handle rather than the whole thumbnail.
Two bugs caught while click-testing, fixed here rather than shipped
and patched after: the search panel never closed after attaching an
image, since the success handler re-triggered focus to keep it open
for attaching several in a row -- which meant it just re-populated
itself forever instead of signaling "done." Fixed to close explicitly;
a click-outside-closes handler was added alongside it, matching the
affordance the top-bar search already has.
A real, independent, pre-existing data bug surfaced during the same
testing: Node#autosave!'s first-time-creation branch never carried
related assets forward from whatever page was previously current --
attach an image, let autosave fire once, and it silently landed on a
fresh, assetless Page row. Long-dormant, not introduced by this work,
just finally exercised by something that made it visible. Fixed inside
the `unless self.autosave` guard specifically -- running this on every
call, not just creation, would overwrite anything attached directly to
an existing autosave in between, a worse bug than the one being fixed.
nodes#show gains a read-only Images section, rendered only when a page
actually has attached images, so an attachment can be confirmed
present without entering the edit/lock cycle -- useful on its own, and
specifically useful the next time an asset bug needs investigating.
Its thumbnail CSS is shared with the edit view's picker via a class
(.thumbnail_list) rather than duplicated under a second name.
---
app/controllers/related_assets_controller.rb | 3 +-
app/models/node.rb | 1 +
app/views/layouts/admin.html.erb | 1 +
app/views/nodes/edit.html.erb | 39 +++++++----
app/views/nodes/show.html.erb | 11 +++
public/javascripts/admin_interface.js | 4 ++
public/javascripts/related_assets.js | 80 ++++++++++++++++++++++
public/stylesheets/admin.css | 75 ++++++++++++++++++++
test/controllers/related_assets_controller_test.rb | 2 +
test/models/node_test.rb | 29 ++++++++
10 files changed, 230 insertions(+), 15 deletions(-)
create mode 100644 public/javascripts/related_assets.js
(limited to 'public/javascripts/admin_interface.js')
diff --git a/app/controllers/related_assets_controller.rb b/app/controllers/related_assets_controller.rb
index ae37d2f..479ebec 100644
--- a/app/controllers/related_assets_controller.rb
+++ b/app/controllers/related_assets_controller.rb
@@ -26,7 +26,8 @@ class RelatedAssetsController < ApplicationController
id: related.id,
asset_id: asset.id,
name: asset.name,
- thumb_url: asset.upload.url(:thumb)
+ thumb_url: asset.upload.url(:thumb),
+ url: node_related_asset_path(@node, related)
}
end
diff --git a/app/models/node.rb b/app/models/node.rb
index 0361c1e..6f435ee 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -80,6 +80,7 @@ class Node < ApplicationRecord
unless self.autosave
self.autosave = Page.create!(:editor => current_user)
+ self.autosave.assets = (self.draft || self.head).assets if self.draft || self.head
self.save!
end
self.autosave.assign_attributes(attributes)
diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb
index 5ae363f..8bbc0d5 100644
--- a/app/views/layouts/admin.html.erb
+++ b/app/views/layouts/admin.html.erb
@@ -13,6 +13,7 @@
+