Skip to content

Instantly share code, notes, and snippets.

@amkisko
Last active May 7, 2024 13:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amkisko/c704c1a6462d573dfa4820ae07d807a6 to your computer and use it in GitHub Desktop.
Save amkisko/c704c1a6462d573dfa4820ae07d807a6 to your computer and use it in GitHub Desktop.
ActiveAdmin v4 tailwind configuration
$ rails new . -n ActiveAdminDemo -c tailwind -a propshaft --skip-test --skip-system-test

$ rails g active_admin:install --skip-users
$ rails tailwindcss:install
$ rails generate active_admin:assets
$ cat tailwind-active_admin.config.js | sed 's/require(`@activeadmin\/activeadmin\/plugin`)/require(`${activeAdminPath}\/plugin.js`)/g' > config/tailwind-active_admin.config.js
$ rm tailwind-active_admin.config.js
$ bundle binstub tailwindcss-rails
$ rails generate active_admin:views
$ echo "active_admin: bin/rails active_admin:watch" >> Procfile.dev

$ vim lib/tasks/active_admin.rake
$ vim config/initializers/active_admin.rb

$ rails g model button clicked:boolean clicked_at:timestamp
$ rails generate active_admin:resource Button

$ rails db:create db:migrate db:seed
$ bin/dev
module ActiveAdmin
class ActionPolicyAdapter < AuthorizationAdapter
def authorized?(action, subject = nil)
target = policy_target(subject)
policy = ActionPolicy.lookup(target)
action = format_action(action, subject)
policy.new(target, user: user).apply(action)
end
def scope_collection(collection, _action = Auth::READ)
target = policy_target(collection)
policy = ActionPolicy.lookup(target)
policy.new(user: user).apply_scope(collection, type: :active_admin)
end
def format_action(action, subject)
case action
when Auth::CREATE
:create?
when Auth::UPDATE
:update?
when Auth::READ
subject.is_a?(Class) ? :index? : :show?
when Auth::DESTROY
subject.is_a?(Class) ? :destroy_all? : :destroy?
else
"#{action}?"
end
end
private
def policy_target(subject)
case subject
when nil
resource.resource_class
when Class
subject.new
else
subject
end
end
end
end
namespace :active_admin do
desc "Build Active Admin Tailwind stylesheets"
task build: :environment do
command = [
Rails.root.join("bin/tailwindcss").to_s,
"-i", Rails.root.join("app/assets/stylesheets/active_admin.css").to_s,
"-o", Rails.root.join("app/assets/builds/active_admin.css").to_s,
"-c", Rails.root.join("config/tailwind-active_admin.config.js").to_s,
"-m"
]
system(*command, exception: true)
end
desc "Watch Active Admin Tailwind stylesheets"
task watch: :environment do
command = [
Rails.root.join("bin/tailwindcss").to_s,
"--watch",
"-i", Rails.root.join("app/assets/stylesheets/active_admin.css").to_s,
"-o", Rails.root.join("app/assets/builds/active_admin.css").to_s,
"-c", Rails.root.join("config/tailwind-active_admin.config.js").to_s,
"-m"
]
system(*command)
end
end
Rake::Task["assets:precompile"].enhance(["active_admin:build"])
Rake::Task["test:prepare"].enhance(["active_admin:build"]) if Rake::Task.task_defined?("test:prepare")
Rake::Task["spec:prepare"].enhance(["tailwindcss:build"]) if Rake::Task.task_defined?("spec:prepare")
Rake::Task["db:test:prepare"].enhance(["tailwindcss:build"]) if Rake::Task.task_defined?("db:test:prepare")
class Current < ActiveSupport::CurrentAttributes
attribute :user
attribute :request_id, :user_agent, :remote_addr
attribute :locale, :time_zone
resets do
I18n.locale = I18n.default_locale
Time.zone = Time.zone_default
ActionReporter.reset_context
end
def user_agent=(user_agent)
super
ActionReporter.context(user_agent: user_agent)
end
def remote_addr=(remote_addr)
super
ActionReporter.context(remote_addr: remote_addr)
end
def locale=(locale)
super
I18n.locale = locale
ActionReporter.context(locale: locale)
end
def time_zone=(time_zone)
super
Time.zone = time_zone
ActionReporter.context(time_zone: time_zone)
end
def user=(user)
super
ActionReporter.audited_user = user
end
end
require_relative "../../app/lib/active_admin/action_policy_adapter"
ActiveAdmin.importmap.draw do
pin "@rails/actioncable", to: "actioncable.esm.js", preload: true
pin "@rails/activestorage", to: "activestorage.esm.js", preload: true
pin "@hotwired/turbo-rails", to: "turbo.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin "application", preload: true
pin_all_from "app/assets/javascripts/controllers", under: "controllers"
end
ActiveAdmin.setup do |config|
# setup
end
# https://guides.rubyonrails.org/security.html
# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
policy.img_src :self, :https, :data
policy.script_src :self, :https
policy.style_src :self, :https, :unsafe_inline
# if Rails.env.production?
# policy.report_uri -> { "https://api.honeybadger.io/v1/browser/csp?api_key=#{HoneybadgerConfig.new.api_key}&report_only=true&env=#{EnvConfig.new.environment}&context[user_id]=#{respond_to?(:current_user) ? current_user&.id : nil}" }
# end
end
# If you are using UJS then enable automatic nonce generation
Rails.application.config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
# Set the nonce only to specific directives
Rails.application.config.content_security_policy_nonce_directives = %w[script-src]
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# Rails.application.config.content_security_policy_report_only = true
const execSync = require('child_process').execSync;
const activeAdminPath = execSync('bundle show activeadmin', { encoding: 'utf-8' }).trim();
module.exports = {
content: [
`${activeAdminPath}/vendor/javascript/flowbite.js`,
`${activeAdminPath}/plugin.js`,
`${activeAdminPath}/app/views/**/*.{arb,erb,html,rb}`,
'./app/admin/**/*.{arb,erb,html,rb}',
'./app/views/active_admin/**/*.{arb,erb,html,rb}',
'./app/views/admin/**/*.{arb,erb,html,rb}',
'./app/javascript/**/*.js'
],
darkMode: "class",
plugins: [
require(`${activeAdminPath}\/plugin.js`)
]
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "active_admin" %>
<% # On page load or when changing themes, best to add inline in `head` to avoid FOUC %>
<%= javascript_tag nonce: true do %>
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
<% end %>
<%= javascript_importmap_tags "active_admin", importmap: ActiveAdmin.importmap %>
<%= javascript_import_module_tag "application" %>
<%= render partial: "honeybadger", locals: { layout: :active_admin } %>
<%= render partial: "favicon" %>
<%= render partial: "fonts" %>
<%= render partial: "scripts" %>
<% if content_for?(:head) %>
<%= yield(:head) %>
<% end %>
<%= javascript_include_tag "https://js.honeybadger.io/v6.8/honeybadger.min.js" nonce: true %>
<% if ENV["HONEYBADGER_API_KEY"].present? %>
<%= javascript_tag nonce: true do %>
if (typeof Honeybadger !== "undefined") {
Honeybadger.configure({
apiKey: "<%= ENV.fetch("HONEYBADGER_API_KEY") %>",
environment: "<%= ENV.fetch("HONEYBADGER_ENV") %>",
revision: "<%= ENV.fetch("HONEYBADGER_REVISION", "unknown") %>",
});
Honeybadger.setContext({
layout: "<%= layout %>",
user_id: "<%= current_user&.id %>"
});
}
<% end %>
<% end %>
<%= javascript_include_tag "https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js", nonce: true, defer: true %>
@w3villa-Khushi-Gupta
Copy link

Hi andrei, I am trying to update my active admin version for 3.1.2 to 4.0.0beta6, i have done the whole setup successfully but i still am not able to link the css in the view. Can you please help me out with this issue? If yes please ping me in linkedIn (https://www.linkedin.com/in/khushi-gupta-910619248/). I would really appreciate the help

@amkisko
Copy link
Author

amkisko commented May 7, 2024

@w3villa-Khushi-Gupta Hey! Do you have source code publicly available? And please elaborate more what do you mean by "to link css in the view"?

I have no LinkedIn profile, so won't contact you there, let's continue it here.

@w3villa-Khushi-Gupta
Copy link

No source code ain't public. I meant that the view in the admin panel is not having any css they are just divs and other things without any styling being implemneted.
Screenshot from 2024-05-07 18-34-48

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment