diff --git a/app/views/layouts/alchemy/admin.html.erb b/app/views/layouts/alchemy/admin.html.erb index 0980bee3d0..7affe444c3 100644 --- a/app/views/layouts/alchemy/admin.html.erb +++ b/app/views/layouts/alchemy/admin.html.erb @@ -35,6 +35,13 @@ <%= render 'alchemy/admin/partials/routes' %> <%= javascript_include_tag('alchemy/admin/all', 'data-turbo-track' => true) %> <%= javascript_importmap_tags("alchemy_admin", importmap: Alchemy.importmap) %> + <% if Alchemy.admin_js_imports.any? %> + + <% end %> <%= yield :javascript_includes %> <%= content_tag :body, id: 'alchemy', class: alchemy_body_class do %> diff --git a/lib/alchemy.rb b/lib/alchemy.rb index 9e52604c72..b4cc25d568 100644 --- a/lib/alchemy.rb +++ b/lib/alchemy.rb @@ -43,6 +43,25 @@ def self.preview_sources=(sources) @_preview_sources = Array(sources) end + # Additional JS modules to be imported in the Alchemy admin UI + # + # Be sure to also pin the modules with +Alchemy.importmap+. + # + # == Example + # + # Alchemy.importmap.pin "flatpickr/de", + # to: "https://ga.jspm.io/npm:flatpickr@4.6.13/dist/l10n/de.js" + # + # Alchemy.admin_js_imports << "flatpickr/de" + # + def self.admin_js_imports + @_admin_js_imports ||= Set.new + end + + def self.admin_js_imports=(sources) + @_admin_js_imports = Set[sources] + end + # Define page publish targets # # A publish target is a ActiveJob that gets performed diff --git a/spec/views/layouts/alchemy/admin.html.erb.spec b/spec/views/layouts/alchemy/admin.html.erb.spec new file mode 100644 index 0000000000..d2eaa9531a --- /dev/null +++ b/spec/views/layouts/alchemy/admin.html.erb.spec @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe "layouts/alchemy/admin.html.erb" do + before do + view.extend Alchemy::Admin::BaseHelper + allow(view).to receive(:alchemy_modules).and_return([]) + allow(view).to receive(:current_alchemy_user).and_return(DummyUser.new) + allow(view).to receive(:configuration).and_return({}) + end + + subject do + render template: "layouts/alchemy/admin" + rendered + end + + context "with Alchemy.admin_js_imports" do + around do |example| + current = Alchemy.admin_js_imports + Alchemy.admin_js_imports << "foo" + example.run + Alchemy.admin_js_imports = current + end + + it "renders the given javascripts module imports" do + expect(subject).to have_selector("script[type=\"module\"]:last-of-type", text: /import "foo"/) + end + end + + context "without Alchemy.admin_js_imports" do + it "does not render the given javascripts module imports" do + expect(subject).to_not have_selector("script[type=\"module\"]:last-of-type", text: /import "foo"/) + end + end +end