voidable-hotwire 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/views/devise/confirmations/new.html.erb +22 -0
- data/app/views/devise/passwords/edit.html.erb +27 -0
- data/app/views/devise/passwords/new.html.erb +21 -0
- data/app/views/devise/registrations/edit.html.erb +50 -0
- data/app/views/devise/registrations/new.html.erb +29 -0
- data/app/views/devise/sessions/new.html.erb +35 -0
- data/app/views/devise/shared/_error_messages.html.erb +10 -0
- data/app/views/devise/shared/_links.html.erb +33 -0
- data/app/views/devise/unlocks/new.html.erb +22 -0
- data/lib/generators/voidable/devise_views/devise_views_generator.rb +15 -0
- data/lib/generators/voidable/install/install_generator.rb +112 -0
- data/lib/generators/voidable/install/templates/_settings_menu.html.erb +31 -0
- data/lib/generators/voidable/install/templates/application_sidebar.html.erb.tt +86 -0
- data/lib/generators/voidable/install/templates/application_topbar.html.erb.tt +69 -0
- data/lib/generators/voidable/install/templates/initializer.rb.tt +2 -0
- data/lib/generators/voidable/install/templates/settings_controller.rb.tt +7 -0
- data/lib/generators/voidable/install/templates/sidebar.html.erb.tt +86 -0
- data/lib/generators/voidable/install/templates/topbar.html.erb.tt +69 -0
- data/lib/generators/voidable/install/templates/voidable-devise.css +37 -0
- data/lib/generators/voidable/install/templates/voidable-layout-sidebar.css +460 -0
- data/lib/generators/voidable/install/templates/voidable-layout-topbar.css +361 -0
- data/lib/generators/voidable/install/templates/voidable-layout.js +41 -0
- data/lib/templates/erb/scaffold/_form.html.erb.tt +80 -0
- data/lib/templates/erb/scaffold/edit.html.erb.tt +18 -0
- data/lib/templates/erb/scaffold/index.html.erb.tt +65 -0
- data/lib/templates/erb/scaffold/new.html.erb.tt +3 -0
- data/lib/templates/erb/scaffold/partial.html.erb.tt +17 -0
- data/lib/templates/erb/scaffold/show.html.erb.tt +56 -0
- data/lib/voidable/hotwire/engine.rb +5 -0
- data/lib/voidable/hotwire/version.rb +1 -1
- metadata +29 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9abae5966616acf1bb8a037ed7eaae7433e5a0c8ac72b47896739281ba0ecd10
|
|
4
|
+
data.tar.gz: 8d570608eeb27e61ffb72429b258040fc7b9a5855457208693541a5312ae34e7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f20748f43e723982c55976bc44df0814b5267d8650074e4c3376d6eeac1a22a9898a2a90590e841e8c78878a85b4f17aae215978877a03b56f8f62133dbac2e8
|
|
7
|
+
data.tar.gz: 7e29e9da0a0736d47e230319b523a704835c56ff4df2e4d47169fb1e309a0b8235508c06747119dd8721b32d918e3d01f4d3143f47fd6b5fbd1a2641a6946967
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="devise-container">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Resend confirmation instructions</h1>
|
|
5
|
+
<p class="devise-description">Enter the email address you used to register and we'll send you a new confirmation link.</p>
|
|
6
|
+
|
|
7
|
+
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post, class: "devise-form" }) do |f| %>
|
|
8
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
9
|
+
|
|
10
|
+
<void-field label="Email">
|
|
11
|
+
<void-input type="email" name="<%= resource_name %>[email]" value="<%= (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>" autofocus autocomplete="email" placeholder="you@example.com"></void-input>
|
|
12
|
+
</void-field>
|
|
13
|
+
|
|
14
|
+
<div class="devise-submit">
|
|
15
|
+
<void-button type="submit" color="success" class="devise-btn-full">Resend confirmation instructions</void-button>
|
|
16
|
+
</div>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<%= render "devise/shared/links" %>
|
|
20
|
+
</div>
|
|
21
|
+
</void-card>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div class="devise-container">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Change your password</h1>
|
|
5
|
+
|
|
6
|
+
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put, class: "devise-form" }) do |f| %>
|
|
7
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
8
|
+
|
|
9
|
+
<%= f.hidden_field :reset_password_token %>
|
|
10
|
+
|
|
11
|
+
<void-field label="New password" helper="6 characters minimum">
|
|
12
|
+
<void-action-input type="password" name="<%= resource_name %>[password]" icon="eye" action-label="Toggle visibility" autofocus autocomplete="new-password"></void-action-input>
|
|
13
|
+
</void-field>
|
|
14
|
+
|
|
15
|
+
<void-field label="Confirm new password">
|
|
16
|
+
<void-action-input type="password" name="<%= resource_name %>[password_confirmation]" icon="eye" action-label="Toggle visibility" autocomplete="new-password"></void-action-input>
|
|
17
|
+
</void-field>
|
|
18
|
+
|
|
19
|
+
<div class="devise-submit">
|
|
20
|
+
<void-button type="submit" color="success" class="devise-btn-full">Change my password</void-button>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<%= render "devise/shared/links" %>
|
|
25
|
+
</div>
|
|
26
|
+
</void-card>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div class="devise-container">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Forgot your password?</h1>
|
|
5
|
+
|
|
6
|
+
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: "devise-form" }) do |f| %>
|
|
7
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
8
|
+
|
|
9
|
+
<void-field label="Email">
|
|
10
|
+
<void-input type="email" name="<%= resource_name %>[email]" value="<%= resource.email %>" autofocus autocomplete="email" placeholder="you@example.com"></void-input>
|
|
11
|
+
</void-field>
|
|
12
|
+
|
|
13
|
+
<div class="devise-submit">
|
|
14
|
+
<void-button type="submit" color="success" class="devise-btn-full">Send reset instructions</void-button>
|
|
15
|
+
</div>
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
<%= render "devise/shared/links" %>
|
|
19
|
+
</div>
|
|
20
|
+
</void-card>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<div class="devise-container devise-container--wide">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Account settings</h1>
|
|
5
|
+
|
|
6
|
+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: "devise-form" }) do |f| %>
|
|
7
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
8
|
+
|
|
9
|
+
<void-field label="Email">
|
|
10
|
+
<void-input type="email" name="<%= resource_name %>[email]" value="<%= resource.email %>" autofocus autocomplete="email"></void-input>
|
|
11
|
+
</void-field>
|
|
12
|
+
|
|
13
|
+
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
|
|
14
|
+
<void-alert>Currently waiting confirmation for: <%= resource.unconfirmed_email %></void-alert>
|
|
15
|
+
<% end %>
|
|
16
|
+
|
|
17
|
+
<void-field label="New password" helper="Leave blank if you don't want to change it">
|
|
18
|
+
<void-action-input type="password" name="<%= resource_name %>[password]" icon="eye" action-label="Toggle visibility" autocomplete="new-password"></void-action-input>
|
|
19
|
+
</void-field>
|
|
20
|
+
|
|
21
|
+
<void-field label="Confirm new password">
|
|
22
|
+
<void-action-input type="password" name="<%= resource_name %>[password_confirmation]" icon="eye" action-label="Toggle visibility" autocomplete="new-password"></void-action-input>
|
|
23
|
+
</void-field>
|
|
24
|
+
|
|
25
|
+
<void-field label="Current password" helper="We need your current password to confirm changes">
|
|
26
|
+
<void-action-input type="password" name="<%= resource_name %>[current_password]" icon="eye" action-label="Toggle visibility" autocomplete="current-password"></void-action-input>
|
|
27
|
+
</void-field>
|
|
28
|
+
|
|
29
|
+
<div class="devise-submit">
|
|
30
|
+
<void-button type="submit" color="success" class="devise-btn-full">Update</void-button>
|
|
31
|
+
</div>
|
|
32
|
+
<% end %>
|
|
33
|
+
</div>
|
|
34
|
+
</void-card>
|
|
35
|
+
|
|
36
|
+
<div class="danger-zone">
|
|
37
|
+
<p class="devise-danger-label">Danger zone</p>
|
|
38
|
+
<void-button variant="outline" color="error" size="sm" onclick="document.getElementById('delete-dialog').open = true">Delete my account</void-button>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<void-dialog id="delete-dialog" heading="Delete account" size="sm">
|
|
42
|
+
<p class="danger-zone-description">
|
|
43
|
+
Are you sure you want to delete your account? This action cannot be undone.
|
|
44
|
+
</p>
|
|
45
|
+
<div class="action-bar">
|
|
46
|
+
<void-button variant="ghost" size="sm" onclick="document.getElementById('delete-dialog').open = false">Cancel</void-button>
|
|
47
|
+
<void-button color="error" size="sm"><a href="<%= registration_path(resource_name) %>" data-turbo-method="delete">Delete</a></void-button>
|
|
48
|
+
</div>
|
|
49
|
+
</void-dialog>
|
|
50
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<div class="devise-container">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Sign up</h1>
|
|
5
|
+
|
|
6
|
+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { class: "devise-form" }) do |f| %>
|
|
7
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
8
|
+
|
|
9
|
+
<void-field label="Email">
|
|
10
|
+
<void-input type="email" name="<%= resource_name %>[email]" value="<%= resource.email %>" autofocus autocomplete="email" placeholder="you@example.com"></void-input>
|
|
11
|
+
</void-field>
|
|
12
|
+
|
|
13
|
+
<void-field label="Password" helper="<%= @minimum_password_length %> characters minimum">
|
|
14
|
+
<void-action-input type="password" name="<%= resource_name %>[password]" icon="eye" action-label="Toggle visibility" autocomplete="new-password" minlength="<%= @minimum_password_length %>"></void-action-input>
|
|
15
|
+
</void-field>
|
|
16
|
+
|
|
17
|
+
<void-field label="Password confirmation">
|
|
18
|
+
<void-action-input type="password" name="<%= resource_name %>[password_confirmation]" icon="eye" action-label="Toggle visibility" autocomplete="new-password"></void-action-input>
|
|
19
|
+
</void-field>
|
|
20
|
+
|
|
21
|
+
<div class="devise-submit">
|
|
22
|
+
<void-button type="submit" color="success" class="devise-btn-full">Sign up</void-button>
|
|
23
|
+
</div>
|
|
24
|
+
<% end %>
|
|
25
|
+
|
|
26
|
+
<%= render "devise/shared/links" %>
|
|
27
|
+
</div>
|
|
28
|
+
</void-card>
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<div class="devise-container">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Sign in</h1>
|
|
5
|
+
|
|
6
|
+
<%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "devise-form" }) do |f| %>
|
|
7
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
8
|
+
|
|
9
|
+
<void-field label="Email">
|
|
10
|
+
<void-input type="email" name="<%= resource_name %>[email]" value="<%= resource.email %>" autofocus autocomplete="email" placeholder="you@example.com"></void-input>
|
|
11
|
+
</void-field>
|
|
12
|
+
|
|
13
|
+
<void-field label="Password">
|
|
14
|
+
<void-action-input type="password" name="<%= resource_name %>[password]" icon="eye" action-label="Toggle visibility" autocomplete="current-password"></void-action-input>
|
|
15
|
+
</void-field>
|
|
16
|
+
|
|
17
|
+
<% if devise_mapping.rememberable? %>
|
|
18
|
+
<void-field label="Remember me">
|
|
19
|
+
<void-switch name="<%= resource_name %>[remember_me]"></void-switch>
|
|
20
|
+
</void-field>
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
<div class="devise-submit">
|
|
24
|
+
<void-button type="submit" color="success" class="devise-btn-full">Sign in</void-button>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<% if devise_mapping.recoverable? %>
|
|
28
|
+
<void-button variant="ghost" class="devise-btn-full"><a href="<%= new_password_path(resource_name) %>">Forgot your password?</a></void-button>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% end %>
|
|
31
|
+
|
|
32
|
+
<%= render "devise/shared/links" %>
|
|
33
|
+
</div>
|
|
34
|
+
</void-card>
|
|
35
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<% if resource.errors.any? %>
|
|
2
|
+
<void-alert color="error" data-turbo-temporary>
|
|
3
|
+
<%= pluralize(resource.errors.count, "error") %> prohibited this operation:
|
|
4
|
+
<ul class="devise-error-list">
|
|
5
|
+
<% resource.errors.full_messages.each do |message| %>
|
|
6
|
+
<li><%= message %></li>
|
|
7
|
+
<% end %>
|
|
8
|
+
</ul>
|
|
9
|
+
</void-alert>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<div class="devise-divider">
|
|
2
|
+
<div class="devise-divider-line"></div>
|
|
3
|
+
<span class="devise-divider-text">or</span>
|
|
4
|
+
<div class="devise-divider-line"></div>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="devise-links">
|
|
8
|
+
<%- if controller_name != 'sessions' %>
|
|
9
|
+
<void-button variant="ghost" class="devise-btn-full"><a href="<%= new_session_path(resource_name) %>">Sign in</a></void-button>
|
|
10
|
+
<% end %>
|
|
11
|
+
|
|
12
|
+
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
|
13
|
+
<void-button variant="ghost" color="info" class="devise-btn-full"><a href="<%= new_registration_path(resource_name) %>">Sign up</a></void-button>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' && controller_name != 'sessions' %>
|
|
17
|
+
<void-button variant="ghost" class="devise-btn-full"><a href="<%= new_password_path(resource_name) %>">Forgot your password?</a></void-button>
|
|
18
|
+
<% end %>
|
|
19
|
+
|
|
20
|
+
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
|
21
|
+
<void-button variant="ghost" class="devise-btn-full"><a href="<%= new_confirmation_path(resource_name) %>">Didn't receive confirmation instructions?</a></void-button>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
|
25
|
+
<void-button variant="ghost" class="devise-btn-full"><a href="<%= new_unlock_path(resource_name) %>">Didn't receive unlock instructions?</a></void-button>
|
|
26
|
+
<% end %>
|
|
27
|
+
|
|
28
|
+
<%- if devise_mapping.omniauthable? %>
|
|
29
|
+
<%- resource_class.omniauth_providers.each do |provider| %>
|
|
30
|
+
<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% end %>
|
|
33
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="devise-container">
|
|
2
|
+
<void-card>
|
|
3
|
+
<div class="devise-card-body">
|
|
4
|
+
<h1 class="devise-heading">Resend unlock instructions</h1>
|
|
5
|
+
<p class="devise-description">Enter your email address and we'll send you instructions to unlock your account.</p>
|
|
6
|
+
|
|
7
|
+
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, class: "devise-form" }) do |f| %>
|
|
8
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
9
|
+
|
|
10
|
+
<void-field label="Email">
|
|
11
|
+
<void-input type="email" name="<%= resource_name %>[email]" value="<%= resource.email %>" autofocus autocomplete="email" placeholder="you@example.com"></void-input>
|
|
12
|
+
</void-field>
|
|
13
|
+
|
|
14
|
+
<div class="devise-submit">
|
|
15
|
+
<void-button type="submit" color="success" class="devise-btn-full">Resend unlock instructions</void-button>
|
|
16
|
+
</div>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<%= render "devise/shared/links" %>
|
|
20
|
+
</div>
|
|
21
|
+
</void-card>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Voidable
|
|
4
|
+
module Generators
|
|
5
|
+
class DeviseViewsGenerator < Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path("../../../../app/views/devise", __dir__)
|
|
7
|
+
|
|
8
|
+
desc "Copy Voidable-styled Devise views into your application"
|
|
9
|
+
|
|
10
|
+
def copy_views
|
|
11
|
+
directory ".", "app/views/devise"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module Voidable
|
|
2
|
+
module Generators
|
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
|
5
|
+
desc "Install Voidable UI into your Rails application"
|
|
6
|
+
|
|
7
|
+
class_option :layout, type: :string, default: "topbar", enum: ["topbar", "sidebar", "switching"],
|
|
8
|
+
desc: "Application layout style (topbar, sidebar, or switching)"
|
|
9
|
+
|
|
10
|
+
def create_initializer
|
|
11
|
+
template "initializer.rb.tt", "config/initializers/voidable.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def pin_packages
|
|
15
|
+
importmap = "config/importmap.rb"
|
|
16
|
+
return unless File.exist?(importmap)
|
|
17
|
+
return if File.read(importmap).include?("@voidable/ui")
|
|
18
|
+
append_to_file importmap, <<~RUBY
|
|
19
|
+
|
|
20
|
+
# Voidable UI
|
|
21
|
+
pin "@voidable/ui", to: "https://ga.jspm.io/npm:@voidable/ui@0.0.1/dist/ui.js"
|
|
22
|
+
pin "@voidable/ui-hotwire", to: "https://ga.jspm.io/npm:@voidable/ui-hotwire@0.0.1/dist/hotwire.js"
|
|
23
|
+
RUBY
|
|
24
|
+
say "Pinned @voidable/ui and @voidable/ui-hotwire in importmap", :green
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def create_layout
|
|
28
|
+
copy_file "_settings_menu.html.erb", "app/views/layouts/_settings_menu.html.erb"
|
|
29
|
+
|
|
30
|
+
case options[:layout]
|
|
31
|
+
when "sidebar"
|
|
32
|
+
template "application_sidebar.html.erb.tt", "app/views/layouts/application.html.erb", force: true
|
|
33
|
+
when "switching"
|
|
34
|
+
template "application_topbar.html.erb.tt", "app/views/layouts/application.html.erb", force: true
|
|
35
|
+
template "topbar.html.erb.tt", "app/views/layouts/topbar.html.erb"
|
|
36
|
+
template "sidebar.html.erb.tt", "app/views/layouts/sidebar.html.erb"
|
|
37
|
+
else
|
|
38
|
+
template "application_topbar.html.erb.tt", "app/views/layouts/application.html.erb", force: true
|
|
39
|
+
end
|
|
40
|
+
say "Created Voidable application layout (#{options[:layout]})", :green
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def create_layout_assets
|
|
44
|
+
copy_file "voidable-layout.js", "app/assets/javascripts/voidable-layout.js"
|
|
45
|
+
copy_file "voidable-devise.css", "app/assets/stylesheets/voidable-devise.css"
|
|
46
|
+
|
|
47
|
+
assets_init = "config/initializers/assets.rb"
|
|
48
|
+
if File.exist?(assets_init) && !File.read(assets_init).include?("javascripts")
|
|
49
|
+
append_to_file assets_init, <<~RUBY
|
|
50
|
+
|
|
51
|
+
# Voidable layout scripts
|
|
52
|
+
Rails.application.config.assets.paths << Rails.root.join("app/assets/javascripts")
|
|
53
|
+
RUBY
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
case options[:layout]
|
|
57
|
+
when "sidebar"
|
|
58
|
+
copy_file "voidable-layout-sidebar.css", "app/assets/stylesheets/voidable-layout.css", force: true
|
|
59
|
+
when "switching"
|
|
60
|
+
copy_file "voidable-layout-topbar.css", "app/assets/stylesheets/voidable-layout-topbar.css"
|
|
61
|
+
copy_file "voidable-layout-sidebar.css", "app/assets/stylesheets/voidable-layout-sidebar.css"
|
|
62
|
+
else
|
|
63
|
+
copy_file "voidable-layout-topbar.css", "app/assets/stylesheets/voidable-layout.css", force: true
|
|
64
|
+
end
|
|
65
|
+
say "Created Voidable layout assets", :green
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def setup_layout_switching
|
|
69
|
+
return unless options[:layout] == "switching"
|
|
70
|
+
|
|
71
|
+
template "settings_controller.rb.tt", "app/controllers/settings_controller.rb"
|
|
72
|
+
|
|
73
|
+
route 'post "toggle_layout", to: "settings#toggle_layout"'
|
|
74
|
+
|
|
75
|
+
inject_into_class "app/controllers/application_controller.rb", "ApplicationController", <<-RUBY
|
|
76
|
+
|
|
77
|
+
layout :resolve_layout
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def resolve_layout
|
|
82
|
+
cookies[:layout] || "topbar"
|
|
83
|
+
end
|
|
84
|
+
RUBY
|
|
85
|
+
|
|
86
|
+
say "Configured layout switching (topbar/sidebar toggle)", :green
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def add_js_import
|
|
90
|
+
js_entrypoint = "app/javascript/application.js"
|
|
91
|
+
return unless File.exist?(js_entrypoint)
|
|
92
|
+
return if File.read(js_entrypoint).include?("@voidable/ui")
|
|
93
|
+
prepend_to_file js_entrypoint, "import \"@voidable/ui\";\nimport \"@voidable/ui-hotwire\";\n\n"
|
|
94
|
+
say "Added Voidable imports to application.js", :green
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
def app_name
|
|
100
|
+
Rails.application.class.module_parent_name.underscore
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
public
|
|
104
|
+
|
|
105
|
+
def install_devise_views
|
|
106
|
+
return unless defined?(Devise)
|
|
107
|
+
generate "voidable:devise_views"
|
|
108
|
+
say "Installed Voidable-styled Devise views", :green
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<void-popover position="<%= local_assigns[:popover_position] || 'top' %>" id="settings-popover">
|
|
2
|
+
<button class="settings-btn" aria-label="View Settings" title="View Settings">
|
|
3
|
+
<i class="ti ti-settings"></i>
|
|
4
|
+
</button>
|
|
5
|
+
<div class="settings-menu">
|
|
6
|
+
<% if defined?(Devise) && user_signed_in? %>
|
|
7
|
+
<div class="settings-menu-item">
|
|
8
|
+
<a href="<%= edit_user_registration_path %>" class="settings-menu-action">
|
|
9
|
+
<i class="ti ti-user"></i>
|
|
10
|
+
Profile
|
|
11
|
+
</a>
|
|
12
|
+
</div>
|
|
13
|
+
<% end %>
|
|
14
|
+
<label class="settings-menu-item">
|
|
15
|
+
<i class="ti ti-moon"></i>
|
|
16
|
+
<span>Dark mode</span>
|
|
17
|
+
<void-switch id="theme-toggle" size="sm" aria-label="Toggle theme"></void-switch>
|
|
18
|
+
</label>
|
|
19
|
+
<% if local_assigns[:layout_toggle] %>
|
|
20
|
+
<div class="settings-menu-item">
|
|
21
|
+
<form action="/toggle_layout" method="post" class="settings-menu-form">
|
|
22
|
+
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
|
|
23
|
+
<button type="submit" class="settings-menu-action">
|
|
24
|
+
<i class="ti ti-<%= local_assigns[:layout_toggle_icon] %>"></i>
|
|
25
|
+
<%= local_assigns[:layout_toggle_label] %>
|
|
26
|
+
</button>
|
|
27
|
+
</form>
|
|
28
|
+
</div>
|
|
29
|
+
<% end %>
|
|
30
|
+
</div>
|
|
31
|
+
</void-popover>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title><%%= content_for(:title) || "<%= app_name.titleize %>" %></title>
|
|
7
|
+
<%%= csrf_meta_tags %>
|
|
8
|
+
<%%= csp_meta_tag %>
|
|
9
|
+
<%%= yield :head %>
|
|
10
|
+
<%%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
|
|
11
|
+
<%%= stylesheet_link_tag "voidable-theme", "data-turbo-track": "reload" %>
|
|
12
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3.44.0/dist/tabler-icons.min.css">
|
|
13
|
+
<%%= stylesheet_link_tag "voidable-layout", "data-turbo-track": "reload" %>
|
|
14
|
+
<%%= stylesheet_link_tag "voidable-devise", "data-turbo-track": "reload" %>
|
|
15
|
+
<%%= javascript_importmap_tags %>
|
|
16
|
+
</head>
|
|
17
|
+
|
|
18
|
+
<body>
|
|
19
|
+
<div class="app-shell">
|
|
20
|
+
<void-sidebar width="220px">
|
|
21
|
+
<div class="sidebar-header">
|
|
22
|
+
<div class="sidebar-brand-initial"><%= app_name.first.upcase %></div>
|
|
23
|
+
<div class="sidebar-brand-info">
|
|
24
|
+
<div class="sidebar-brand-name"><%= app_name.titleize %></div>
|
|
25
|
+
<div class="sidebar-brand-env">Production</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<nav class="sidebar-nav">
|
|
30
|
+
<div class="sidebar-nav-section">
|
|
31
|
+
<div class="sidebar-nav-label">Main</div>
|
|
32
|
+
<div class="sidebar-nav-item">
|
|
33
|
+
<%%= link_to "Dashboard", root_path %>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
</nav>
|
|
38
|
+
|
|
39
|
+
<div class="sidebar-footer">
|
|
40
|
+
<div class="sidebar-footer-row">
|
|
41
|
+
<%% if defined?(Devise) && user_signed_in? %>
|
|
42
|
+
<span class="sidebar-user-email"><%%= current_user.email %></span>
|
|
43
|
+
<%% end %>
|
|
44
|
+
<%%= render "layouts/settings_menu", popover_position: "top" %>
|
|
45
|
+
</div>
|
|
46
|
+
<%% if defined?(Devise) && user_signed_in? %>
|
|
47
|
+
<void-button variant="ghost" size="sm" class="sidebar-sign-in"><a href="<%%= destroy_user_session_path %>" data-turbo-method="delete">Sign out</a></void-button>
|
|
48
|
+
<%% elsif defined?(Devise) %>
|
|
49
|
+
<void-button variant="ghost" size="sm" class="sidebar-sign-in"><a href="<%%= new_user_session_path %>">Sign in</a></void-button>
|
|
50
|
+
<%% end %>
|
|
51
|
+
</div>
|
|
52
|
+
</void-sidebar>
|
|
53
|
+
|
|
54
|
+
<main class="app-main">
|
|
55
|
+
<div class="app-content-header">
|
|
56
|
+
<div class="app-content-header-left">
|
|
57
|
+
<span class="app-content-header-breadcrumb"><%%= content_for(:breadcrumb) || content_for(:title) || "<%= app_name.titleize %>" %></span>
|
|
58
|
+
<%% if content_for?(:subtitle) %>
|
|
59
|
+
<span class="app-content-header-subtitle"><%%= content_for(:subtitle) %></span>
|
|
60
|
+
<%% end %>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="app-content-header-right">
|
|
63
|
+
<void-action-input icon="search" placeholder="Search…" size="sm" tooltip-position="bottom" class="app-content-header-search"></void-action-input>
|
|
64
|
+
<%%= content_for(:header_actions) %>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="app-content-body">
|
|
68
|
+
<%% if notice.present? %>
|
|
69
|
+
<div class="flash-messages">
|
|
70
|
+
<void-alert color="success" dismissible><%%= notice %></void-alert>
|
|
71
|
+
</div>
|
|
72
|
+
<%% end %>
|
|
73
|
+
<%% if alert.present? %>
|
|
74
|
+
<div class="flash-messages">
|
|
75
|
+
<void-alert color="error" dismissible><%%= alert %></void-alert>
|
|
76
|
+
</div>
|
|
77
|
+
<%% end %>
|
|
78
|
+
|
|
79
|
+
<%%= yield %>
|
|
80
|
+
</div>
|
|
81
|
+
</main>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<%%= javascript_include_tag "voidable-layout", "data-turbo-track": "reload" %>
|
|
85
|
+
</body>
|
|
86
|
+
</html>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title><%%= content_for(:title) || "<%= app_name.titleize %>" %></title>
|
|
7
|
+
<%%= csrf_meta_tags %>
|
|
8
|
+
<%%= csp_meta_tag %>
|
|
9
|
+
<%%= yield :head %>
|
|
10
|
+
<%%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
|
|
11
|
+
<%%= stylesheet_link_tag "voidable-theme", "data-turbo-track": "reload" %>
|
|
12
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3.44.0/dist/tabler-icons.min.css">
|
|
13
|
+
<%%= stylesheet_link_tag "voidable-layout", "data-turbo-track": "reload" %>
|
|
14
|
+
<%%= stylesheet_link_tag "voidable-devise", "data-turbo-track": "reload" %>
|
|
15
|
+
<%%= javascript_importmap_tags %>
|
|
16
|
+
</head>
|
|
17
|
+
|
|
18
|
+
<body>
|
|
19
|
+
<nav class="app-nav">
|
|
20
|
+
<div class="app-nav-inner">
|
|
21
|
+
<a href="/" class="app-nav-brand"><%= app_name.titleize %></a>
|
|
22
|
+
<div class="app-nav-right">
|
|
23
|
+
<span class="app-nav-auth">
|
|
24
|
+
<%% if defined?(Devise) && user_signed_in? %>
|
|
25
|
+
<span><%%= current_user.email %></span>
|
|
26
|
+
<%% elsif defined?(Devise) %>
|
|
27
|
+
<a href="<%%= new_user_session_path %>">Sign in</a>
|
|
28
|
+
<%% end %>
|
|
29
|
+
</span>
|
|
30
|
+
<%%= render "layouts/settings_menu", popover_position: "bottom" %>
|
|
31
|
+
<%% if defined?(Devise) && user_signed_in? %>
|
|
32
|
+
<void-button variant="ghost" size="sm"><a href="<%%= destroy_user_session_path %>" data-turbo-method="delete">Sign out</a></void-button>
|
|
33
|
+
<%% end %>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</nav>
|
|
37
|
+
|
|
38
|
+
<main class="app-main">
|
|
39
|
+
<div class="app-content-header">
|
|
40
|
+
<div class="app-content-header-left">
|
|
41
|
+
<span class="app-content-header-breadcrumb"><%%= content_for(:breadcrumb) || content_for(:title) || "<%= app_name.titleize %>" %></span>
|
|
42
|
+
<%% if content_for?(:subtitle) %>
|
|
43
|
+
<span class="app-content-header-subtitle"><%%= content_for(:subtitle) %></span>
|
|
44
|
+
<%% end %>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="app-content-header-right">
|
|
47
|
+
<void-action-input icon="search" placeholder="Search..." size="sm" tooltip-position="bottom" class="app-content-header-search"></void-action-input>
|
|
48
|
+
<%%= content_for(:header_actions) %>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="app-content-body">
|
|
52
|
+
<%% if notice.present? %>
|
|
53
|
+
<div class="flash-messages">
|
|
54
|
+
<void-alert color="success" dismissible><%%= notice %></void-alert>
|
|
55
|
+
</div>
|
|
56
|
+
<%% end %>
|
|
57
|
+
<%% if alert.present? %>
|
|
58
|
+
<div class="flash-messages">
|
|
59
|
+
<void-alert color="error" dismissible><%%= alert %></void-alert>
|
|
60
|
+
</div>
|
|
61
|
+
<%% end %>
|
|
62
|
+
|
|
63
|
+
<%%= yield %>
|
|
64
|
+
</div>
|
|
65
|
+
</main>
|
|
66
|
+
|
|
67
|
+
<%%= javascript_include_tag "voidable-layout", "data-turbo-track": "reload" %>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|