diff --git a/Gemfile.lock b/Gemfile.lock
index c53bc1c..48fb071 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,8 +1,8 @@
PATH
remote: .
specs:
- dev_toolbar (0.1.0)
- rails (~> 7.0)
+ dev_toolbar (2.1.0)
+ rails (>= 7.0)
GEM
remote: https://rubygems.org/
@@ -122,6 +122,8 @@ GEM
nio4r (2.7.3)
nokogiri (1.16.5-x86_64-darwin)
racc (~> 1.4)
+ nokogiri (1.16.5-x86_64-linux)
+ racc (~> 1.4)
psych (5.1.2)
stringio
racc (1.8.0)
@@ -180,6 +182,7 @@ GEM
PLATFORMS
x86_64-darwin-22
+ x86_64-linux
DEPENDENCIES
bundler (~> 2.0)
diff --git a/README.md b/README.md
index 559641e..f0bca1a 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,16 @@ if Rails.env.development?
end
```
+Include the JavaScript:
+```rb
+# config/importmap.rb
+pin "dev_toolbar", to: "dev_toolbar/index.js"
+pin "dev_toolbar/toolbar", to: "dev_toolbar/toolbar.js"
+
+# app/javascripts/application.js
+import "dev_toolbar"
+```
+
These routes will now appear on every page in your app while in development.
## Updating the gem
diff --git a/app/assets/javascripts/dev_toolbar/index.js b/app/assets/javascripts/dev_toolbar/index.js
new file mode 100644
index 0000000..b343c20
--- /dev/null
+++ b/app/assets/javascripts/dev_toolbar/index.js
@@ -0,0 +1,34 @@
+import Toolbar from "dev_toolbar/toolbar"
+
+function waitForElementToExist(selector) {
+ return new Promise(resolve => {
+ if (document.querySelector(selector)) {
+ return resolve(document.querySelector(selector));
+ }
+
+ const observer = new MutationObserver(() => {
+ if (document.querySelector(selector)) {
+ resolve(document.querySelector(selector));
+ observer.disconnect();
+ }
+ });
+
+ observer.observe(document.body, {
+ subtree: true,
+ childList: true,
+ });
+ });
+}
+const loadEvent = self.hasOwnProperty("Turbo") ? "turbo:load" : "DOMContentLoaded";
+
+document.addEventListener(loadEvent, function() {
+ if (!document.getElementById("dev-toolbar")) {
+ Toolbar.render();
+ }
+ waitForElementToExist("#dev-toolbar-toggle").then( () => {
+ document.getElementById("dev-toolbar-toggle").addEventListener("click", function() {
+ var links = document.getElementById("dev-toolbar-links");
+ links.classList.toggle("hidden");
+ });
+ });
+});
diff --git a/app/assets/javascripts/dev_toolbar/toolbar.js b/app/assets/javascripts/dev_toolbar/toolbar.js
new file mode 100644
index 0000000..619726b
--- /dev/null
+++ b/app/assets/javascripts/dev_toolbar/toolbar.js
@@ -0,0 +1,24 @@
+export default class Toolbar {
+ static render() {
+ const configuration = document.querySelector("meta[name=dev_toolbar_config]")
+ const defined_links = JSON.parse(configuration.content)
+ let toolbar_links = ``
+ for (let index = 0; index < defined_links.length; index++) {
+ const link = defined_links[index];
+ toolbar_links += `${link.name}`
+ }
+ const toolbar_html = `
+
+ `
+ document.body.insertAdjacentHTML('beforeend', toolbar_html)
+ }
+
+}
+export { Toolbar }
diff --git a/app/assets/stylesheets/dev_toolbar.css b/app/assets/stylesheets/dev_toolbar.css
new file mode 100644
index 0000000..a110d10
--- /dev/null
+++ b/app/assets/stylesheets/dev_toolbar.css
@@ -0,0 +1,41 @@
+#dev-toolbar {
+ position: fixed;
+ right: 0;
+ top: 50vh;
+ transform: translateY(-50%);
+ background-color: #f0f0f0;
+ border: 1px solid #ccc;
+ z-index: 1000;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
+ color: #808080;
+}
+
+#dev-toolbar-toggle {
+ all: unset;
+ font-size: 2em;
+ border: none;
+ cursor: pointer;
+ line-height: 1.5;
+ padding: 0 10px;
+ text-decoration: none;
+}
+
+#dev-toolbar-links {
+ display: flex;
+ flex-direction: column;
+}
+
+.dev-toolbar-link {
+ padding: 5px 10px;
+ border-bottom: 1px #f0f0f0 solid;
+ color: #808080;
+ text-decoration: none;
+ background-color: white;
+}
+
+#dev-toolbar-links.hidden {
+ display: none;
+}
diff --git a/lib/dev_toolbar/app/controllers/dev_toolbar/erd_controller.rb b/app/controllers/dev_toolbar/erd_controller.rb
similarity index 75%
rename from lib/dev_toolbar/app/controllers/dev_toolbar/erd_controller.rb
rename to app/controllers/dev_toolbar/erd_controller.rb
index 07a805e..d42f8e7 100644
--- a/lib/dev_toolbar/app/controllers/dev_toolbar/erd_controller.rb
+++ b/app/controllers/dev_toolbar/erd_controller.rb
@@ -4,7 +4,7 @@ class ErdController < ActionController::Base
def show
@erd_path = Rails.root.join("erd.png")
- render :show
+ render "dev_toolbar/erd/show", formats: [:html]
end
end
end
diff --git a/lib/dev_toolbar/app/views/dev_toolbar/erd/show.html.erb b/app/views/dev_toolbar/erd/show.html.erb
similarity index 100%
rename from lib/dev_toolbar/app/views/dev_toolbar/erd/show.html.erb
rename to app/views/dev_toolbar/erd/show.html.erb
diff --git a/lib/dev_toolbar/engine.rb b/lib/dev_toolbar/engine.rb
index 046d601..4703ef2 100644
--- a/lib/dev_toolbar/engine.rb
+++ b/lib/dev_toolbar/engine.rb
@@ -2,9 +2,25 @@ module DevToolbar
class Engine < ::Rails::Engine
isolate_namespace DevToolbar
- config.autoload_paths << File.expand_path("../app/controllers", __FILE__)
- config.paths["app/views"] << File.expand_path("../app/views", __FILE__)
-
+ config.assets.paths << root.join("app/assets/stylesheets")
+
+ initializer "dev_toolbar.assets_precompile", group: :all do |app|
+ # Only configure asset precompilation if Sprockets is available
+ if defined?(Sprockets) && app.config.respond_to?(:assets)
+ app.config.assets.precompile += [
+ "dev_toolbar/toolbar.js",
+ "dev_toolbar/index.js",
+ ]
+ end
+ end
+
+ initializer "dev_toolbar.add_static_assets_middleware" do |app|
+ app.middleware.use ::Rack::Static,
+ # the url prefix to intercept
+ urls: ["/dev_toolbar"],
+ root: "#{root}/app/"
+ end
+
initializer "dev_toolbar.add_routes", after: :add_routing_paths do |app|
app.routes.append do
get "/erd", to: "dev_toolbar/erd#show"
diff --git a/lib/dev_toolbar/middleware.rb b/lib/dev_toolbar/middleware.rb
index d1ee2d0..ebf6516 100644
--- a/lib/dev_toolbar/middleware.rb
+++ b/lib/dev_toolbar/middleware.rb
@@ -10,65 +10,10 @@ def call(env)
if Rails.env.development? && headers["Content-Type"]&.include?("text/html")
response_body = response.body
toolbar_html = <<-HTML
-
-
-
+
HTML
- response_body.sub!('