maquina 0.4.0 → 0.5.1
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/.ruby-version +1 -0
 - data/Gemfile +1 -0
 - data/Gemfile.lock +163 -179
 - data/app/controllers/concerns/maquina/authenticate.rb +33 -13
 - data/app/controllers/concerns/maquina/resourceful.rb +1 -1
 - data/app/controllers/maquina/first_runs_controller.rb +43 -0
 - data/app/controllers/maquina/sessions_controller.rb +22 -25
 - data/app/helpers/maquina/application_helper.rb +3 -5
 - data/app/models/concerns/maquina/searchable.rb +4 -0
 - data/app/models/maquina/organization.rb +2 -0
 - data/app/models/maquina/user.rb +2 -0
 - data/app/views/layouts/maquina/sessions.html.erb +6 -4
 - data/app/views/maquina/accept_invitations/new_view.rb +1 -1
 - data/app/views/maquina/application/alert.rb +4 -4
 - data/app/views/maquina/application/components/action_text_component.rb +1 -1
 - data/app/views/maquina/application/components/checkbox_component.rb +1 -1
 - data/app/views/maquina/application/components/date_component.rb +1 -1
 - data/app/views/maquina/application/components/file_component.rb +1 -1
 - data/app/views/maquina/application/components/input_component.rb +1 -1
 - data/app/views/maquina/application/components/select_component.rb +1 -1
 - data/app/views/maquina/application/components/text_area_component.rb +1 -1
 - data/app/views/maquina/application/edit.rb +1 -1
 - data/app/views/maquina/application/form.rb +1 -1
 - data/app/views/maquina/application/index_header.rb +1 -1
 - data/app/views/maquina/application/index_modal.rb +1 -1
 - data/app/views/maquina/application/index_table.rb +1 -1
 - data/app/views/maquina/application/new.rb +1 -1
 - data/app/views/maquina/application/sessions_header.rb +5 -3
 - data/app/views/maquina/application_view.rb +1 -1
 - data/app/views/maquina/first_runs/form.rb +28 -0
 - data/app/views/maquina/first_runs/show.html.erb +5 -0
 - data/app/views/maquina/form.rb +44 -0
 - data/app/views/maquina/navbar/menu.rb +1 -1
 - data/app/views/maquina/navbar/menu_item_link.rb +1 -1
 - data/app/views/maquina/navbar/mobile_button.rb +1 -1
 - data/app/views/maquina/navbar/mobile_menu.rb +1 -1
 - data/app/views/maquina/navbar/notification.rb +1 -1
 - data/app/views/maquina/navbar/profile.rb +1 -1
 - data/app/views/maquina/navbar/profile_button.rb +1 -1
 - data/app/views/maquina/navbar/profile_menu.rb +1 -1
 - data/app/views/maquina/navbar/profile_menu_item_link.rb +1 -1
 - data/app/views/maquina/navbar/search.rb +1 -1
 - data/app/views/maquina/navbar/title.rb +1 -1
 - data/app/views/maquina/sessions/form.rb +3 -4
 - data/app/views/maquina/sessions/new.html.erb +1 -4
 - data/config/importmap.rb +7 -6
 - data/config/locales/flash.es.yml +14 -5
 - data/config/locales/forms.es.yml +13 -1
 - data/config/locales/models.es.yml +1 -0
 - data/config/locales/views.es.yml +8 -0
 - data/config/routes.rb +1 -0
 - data/lib/generators/maquina/install_stimulus_controllers/install_stimulus_controllers_generator.rb +23 -0
 - data/lib/maquina/version.rb +1 -1
 - data/lib/maquina.rb +2 -2
 - metadata +31 -74
 - data/app/views/maquina/sessions/create.turbo_stream.erb +0 -11
 
| 
         @@ -2,55 +2,52 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Maquina
         
     | 
| 
       4 
4 
     | 
    
         
             
              class SessionsController < ApplicationController
         
     | 
| 
      
 5 
     | 
    
         
            +
                allow_unauthenticated_access only: [:new, :create]
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       5 
7 
     | 
    
         
             
                layout "maquina/sessions"
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
                before_action :ensure_user_exists, only: :new
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       7 
11 
     | 
    
         
             
                def new
         
     | 
| 
       8 
     | 
    
         
            -
                  @ 
     | 
| 
       9 
     | 
    
         
            -
                  @return_to = nil if @return_to == "/" || @return_to == "%2F"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @user = Maquina::User.new
         
     | 
| 
       10 
13 
     | 
    
         
             
                end
         
     | 
| 
       11 
14 
     | 
    
         | 
| 
       12 
15 
     | 
    
         
             
                def create
         
     | 
| 
       13 
     | 
    
         
            -
                   
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  @return_to = params.dig(:return_to)
         
     | 
| 
       16 
     | 
    
         
            -
                  result = create_session(user, @return_to)
         
     | 
| 
       17 
     | 
    
         
            -
                  return redirect_to(result, status: :see_other, format: :html) if result.present?
         
     | 
| 
      
 16 
     | 
    
         
            +
                  reset_session
         
     | 
| 
       18 
17 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                   
     | 
| 
       20 
     | 
    
         
            -
                  flash.now.alert = t("flash.sessions.create.alert")
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @user = Maquina::User.authenticate_by(email: params.dig(:email), password: params.dig(:password))
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                   
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
       24 
     | 
    
         
            -
                     
     | 
| 
      
 20 
     | 
    
         
            +
                  if @user.present?
         
     | 
| 
      
 21 
     | 
    
         
            +
                    active_session = start_new_session_for(@user)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    if active_session.present?
         
     | 
| 
      
 23 
     | 
    
         
            +
                      return redirect_to(calculate_redirect_path(active_session), notice: t("flash.sessions.create.notice"), status: :see_other)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
       25 
25 
     | 
    
         
             
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  @user = Maquina::User.new(email: params.dig(:email))
         
     | 
| 
      
 28 
     | 
    
         
            +
                  flash.now.alert = t("flash.sessions.create.alert")
         
     | 
| 
      
 29 
     | 
    
         
            +
                  render :new, status: :unprocessable_entity
         
     | 
| 
       26 
30 
     | 
    
         
             
                end
         
     | 
| 
       27 
31 
     | 
    
         | 
| 
       28 
32 
     | 
    
         
             
                def destroy
         
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
      
 33 
     | 
    
         
            +
                  reset_session
         
     | 
| 
       30 
34 
     | 
    
         
             
                  Maquina::Current.reset
         
     | 
| 
       31 
35 
     | 
    
         | 
| 
       32 
36 
     | 
    
         
             
                  flash.notice = t("flash.sessions.destroy.notice")
         
     | 
| 
       33 
     | 
    
         
            -
                  redirect_to main_app. 
     | 
| 
      
 37 
     | 
    
         
            +
                  redirect_to main_app.sign_in_path, status: :see_other
         
     | 
| 
       34 
38 
     | 
    
         
             
                end
         
     | 
| 
       35 
39 
     | 
    
         | 
| 
       36 
40 
     | 
    
         
             
                private
         
     | 
| 
       37 
41 
     | 
    
         | 
| 
      
 42 
     | 
    
         
            +
                def ensure_user_exists
         
     | 
| 
      
 43 
     | 
    
         
            +
                  redirect_to maquina.first_run_url if Maquina::User.none?
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       38 
46 
     | 
    
         
             
                def calculate_redirect_path(active_session)
         
     | 
| 
       39 
47 
     | 
    
         
             
                  return maquina.new_multifactor_path if active_session.user.multifactor?
         
     | 
| 
       40 
48 
     | 
    
         
             
                  return active_session.return_url if active_session.return_url.present?
         
     | 
| 
       41 
49 
     | 
    
         | 
| 
       42 
50 
     | 
    
         
             
                  active_session.user.management? ? maquina.root_path : main_app.root_path
         
     | 
| 
       43 
51 
     | 
    
         
             
                end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                def create_session(user, return_to)
         
     | 
| 
       46 
     | 
    
         
            -
                  return nil if user.blank?
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                  active_session = ActiveSession.create(user: user, user_agent: request.user_agent, remote_addr: request.remote_ip, return_url: return_to)
         
     | 
| 
       49 
     | 
    
         
            -
                  return nil if !active_session.persisted?
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  session["--active_session"] = active_session.id
         
     | 
| 
       52 
     | 
    
         
            -
                  flash.notice = t("flash.sessions.create.notice")
         
     | 
| 
       53 
     | 
    
         
            -
                  calculate_redirect_path(active_session)
         
     | 
| 
       54 
     | 
    
         
            -
                end
         
     | 
| 
       55 
52 
     | 
    
         
             
              end
         
     | 
| 
       56 
53 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,12 +2,10 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Maquina
         
     | 
| 
       4 
4 
     | 
    
         
             
              module ApplicationHelper
         
     | 
| 
       5 
     | 
    
         
            -
                def maquina_importmap_tags(entry_point = "application",  
     | 
| 
      
 5 
     | 
    
         
            +
                def maquina_importmap_tags(entry_point = "application", importmap: Maquina.configuration.importmap)
         
     | 
| 
       6 
6 
     | 
    
         
             
                  safe_join [
         
     | 
| 
       7 
     | 
    
         
            -
                    javascript_inline_importmap_tag( 
     | 
| 
       8 
     | 
    
         
            -
                    javascript_importmap_module_preload_tags( 
     | 
| 
       9 
     | 
    
         
            -
                    (javascript_importmap_shim_nonce_configuration_tag if shim),
         
     | 
| 
       10 
     | 
    
         
            -
                    (javascript_importmap_shim_tag if shim),
         
     | 
| 
      
 7 
     | 
    
         
            +
                    javascript_inline_importmap_tag(importmap.to_json(resolver: self)),
         
     | 
| 
      
 8 
     | 
    
         
            +
                    javascript_importmap_module_preload_tags(importmap),
         
     | 
| 
       11 
9 
     | 
    
         
             
                    javascript_import_module_tag(entry_point)
         
     | 
| 
       12 
10 
     | 
    
         
             
                  ].compact, "\n"
         
     | 
| 
       13 
11 
     | 
    
         
             
                end
         
     | 
    
        data/app/models/maquina/user.rb
    CHANGED
    
    | 
         @@ -6,11 +6,13 @@ module Maquina 
     | 
|
| 
       6 
6 
     | 
    
         
             
                include Maquina::AuthenticateBy
         
     | 
| 
       7 
7 
     | 
    
         
             
                include Maquina::Blockeable
         
     | 
| 
       8 
8 
     | 
    
         
             
                include Maquina::Multifactor
         
     | 
| 
      
 9 
     | 
    
         
            +
                # include Maquina::Searchable
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
                PASSWORD_COMPLEXITY_REGEX = /\A(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#-=+])[A-Za-z\d@$!%*?&#-=+]{8,}\z/
         
     | 
| 
       11 
12 
     | 
    
         
             
                has_secure_password
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
14 
     | 
    
         
             
                has_many :memberships, class_name: "Maquina::Membership", foreign_key: :maquina_user_id, inverse_of: :user
         
     | 
| 
      
 15 
     | 
    
         
            +
                has_many :active_sessions, class_name: "Maquina::ActiveSession", foreign_key: :maquina_user_id, dependent: :destroy
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
       15 
17 
     | 
    
         
             
                validates :email, presence: true, uniqueness: true, format: {with: URI::MailTo::EMAIL_REGEXP}
         
     | 
| 
       16 
18 
     | 
    
         
             
                validates :password, format: {with: PASSWORD_COMPLEXITY_REGEX}, unless: ->(user) { user.password.blank? }
         
     | 
| 
         @@ -3,18 +3,20 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
              <head>
         
     | 
| 
       4 
4 
     | 
    
         
             
                <title><%= t("application_name") %></title>
         
     | 
| 
       5 
5 
     | 
    
         
             
                <meta name="viewport" content="width=device-width,initial-scale=1">
         
     | 
| 
      
 6 
     | 
    
         
            +
                <meta name="apple-mobile-web-app-capable" content="yes">
         
     | 
| 
       6 
7 
     | 
    
         
             
                <%= csrf_meta_tags %>
         
     | 
| 
       7 
8 
     | 
    
         
             
                <%= csp_meta_tag %>
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                <%=  
     | 
| 
      
 10 
     | 
    
         
            +
                <%= yield :head %>
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
      
 12 
     | 
    
         
            +
                <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
         
     | 
| 
       11 
13 
     | 
    
         
             
                <%= maquina_importmap_tags %>
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                <%= turbo_refreshes_with method: :morph, scroll: :preserve %>
         
     | 
| 
       12 
16 
     | 
    
         
             
              </head>
         
     | 
| 
       13 
17 
     | 
    
         | 
| 
       14 
18 
     | 
    
         
             
              <body class="h-full">
         
     | 
| 
       15 
     | 
    
         
            -
                <%=  
     | 
| 
       16 
     | 
    
         
            -
                  <%= render Maquina::Application::Alert.new(flash) %>
         
     | 
| 
       17 
     | 
    
         
            -
                <% end %>
         
     | 
| 
      
 19 
     | 
    
         
            +
                <%= render Maquina::Application::Alert.new(flash) %>
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
       19 
21 
     | 
    
         
             
                <main class="container mx-auto">
         
     | 
| 
       20 
22 
     | 
    
         
             
                  <%= yield %>
         
     | 
| 
         @@ -12,7 +12,7 @@ module Maquina 
     | 
|
| 
       12 
12 
     | 
    
         
             
                    @resource = resource
         
     | 
| 
       13 
13 
     | 
    
         
             
                  end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                  def  
     | 
| 
      
 15 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       16 
16 
     | 
    
         
             
                    div(class: "mt-8 sm:mx-auto sm:w-full sm:max-w-md") do
         
     | 
| 
       17 
17 
     | 
    
         
             
                      div(class: "bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10") do
         
     | 
| 
       18 
18 
     | 
    
         
             
                        @resource.new_record? ? invalid_invitation : build_form
         
     | 
| 
         @@ -6,17 +6,17 @@ module Maquina 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  include Maquina::ApplicationView
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
                  def initialize(flash)
         
     | 
| 
       9 
     | 
    
         
            -
                    notice = flash.notice
         
     | 
| 
       10 
     | 
    
         
            -
                    alert = flash.alert
         
     | 
| 
      
 9 
     | 
    
         
            +
                    notice = flash.notice || flash.now[:notice]
         
     | 
| 
      
 10 
     | 
    
         
            +
                    alert = flash.alert || flash.now[:alert]
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                    @flash = notice || alert
         
     | 
| 
       13 
13 
     | 
    
         
             
                    @success = notice.present?
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  def  
     | 
| 
      
 16 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       17 
17 
     | 
    
         
             
                    return if @flash.blank?
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                    div(aria_live: "assertive", class: "pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6 z-30", data: {controller: "alert" 
     | 
| 
      
 19 
     | 
    
         
            +
                    div(aria_live: "assertive", class: "pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6 z-30", data: {controller: "alert"}) do
         
     | 
| 
       20 
20 
     | 
    
         
             
                      div(class: "flex w-full flex-col items-center space-y-4 sm:items-end hidden", data: transition_attributes) do
         
     | 
| 
       21 
21 
     | 
    
         
             
                        div(class: "pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5") do
         
     | 
| 
       22 
22 
     | 
    
         
             
                          div(class: "p-4") do
         
     | 
| 
         @@ -6,7 +6,7 @@ module Maquina 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  include ApplicationView
         
     | 
| 
       7 
7 
     | 
    
         
             
                  register_element :turbo_frame
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                  def  
     | 
| 
      
 9 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       10 
10 
     | 
    
         
             
                    div(data_controller: "modal", class: "modal", data_modal_backdrop_outlet: ".modal-backdrop") do
         
     | 
| 
       11 
11 
     | 
    
         
             
                      div(class: "hidden fixed inset-0 z-30 overflow-y-auto", aria_labelledby: "modal-title", role: "dialog",
         
     | 
| 
       12 
12 
     | 
    
         
             
                        aria_modal: "true", data_modal_target: "container") do
         
     | 
| 
         @@ -13,7 +13,7 @@ module Maquina 
     | 
|
| 
       13 
13 
     | 
    
         
             
                    @pagination = pagination
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  def  
     | 
| 
      
 16 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       17 
17 
     | 
    
         
             
                    div(class: "mt-8 flex flex-col") do
         
     | 
| 
       18 
18 
     | 
    
         
             
                      div(class: "-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8") do
         
     | 
| 
       19 
19 
     | 
    
         
             
                        div(class: "inline-block min-w-full py-2 align-middle md:px-6 lg:px-8") do
         
     | 
| 
         @@ -5,15 +5,17 @@ module Maquina 
     | 
|
| 
       5 
5 
     | 
    
         
             
                class SessionsHeader < Phlex::HTML
         
     | 
| 
       6 
6 
     | 
    
         
             
                  include Maquina::ApplicationView
         
     | 
| 
       7 
7 
     | 
    
         
             
                  include Phlex::DeferredRender
         
     | 
| 
      
 8 
     | 
    
         
            +
                  include Phlex::Rails::Helpers::Translate
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                  def initialize(brand_icon:)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(brand_icon:, translation_key: "maquina.application.sessions_header")
         
     | 
| 
       10 
11 
     | 
    
         
             
                    @brand_icon = brand_icon
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @translation_key = translation_key
         
     | 
| 
       11 
13 
     | 
    
         
             
                  end
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                  def  
     | 
| 
      
 15 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       14 
16 
     | 
    
         
             
                    div(class: "sm:mx-auto sm:w-full sm:max-w-md") do
         
     | 
| 
       15 
17 
     | 
    
         
             
                      image_tag(@brand_icon, class: "mx-auto h-12 w-auto", alt: t("application_name"))
         
     | 
| 
       16 
     | 
    
         
            -
                      h2(class: "mt-6 text-center text-3xl font-bold tracking-tight text-skin-base") { t(".title") }
         
     | 
| 
      
 18 
     | 
    
         
            +
                      h2(class: "mt-6 text-center text-3xl font-bold tracking-tight text-skin-base") { t("#{@translation_key}.title") }
         
     | 
| 
       17 
19 
     | 
    
         | 
| 
       18 
20 
     | 
    
         
             
                      if @description.present?
         
     | 
| 
       19 
21 
     | 
    
         
             
                        p(class: "mt-2 text-center text-sm text-skin-dimmed") do
         
     | 
| 
         @@ -3,7 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Maquina
         
     | 
| 
       4 
4 
     | 
    
         
             
              module ApplicationView
         
     | 
| 
       5 
5 
     | 
    
         
             
                include Maquina::Engine.routes.url_helpers
         
     | 
| 
       6 
     | 
    
         
            -
                include Phlex::Rails::Helpers:: 
     | 
| 
      
 6 
     | 
    
         
            +
                include Phlex::Rails::Helpers::Translate
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
                delegate :resource_class, :l, :default_url_options, :policy_class, :show_link, :allowed_to?, to: :helpers
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Maquina
         
     | 
| 
      
 2 
     | 
    
         
            +
              module FirstRuns
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Form < Phlex::HTML
         
     | 
| 
      
 4 
     | 
    
         
            +
                  include Maquina::ApplicationView
         
     | 
| 
      
 5 
     | 
    
         
            +
                  include Maquina::Form
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(resource)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @resource = resource
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @scope = "first_runs"
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def view_template
         
     | 
| 
      
 13 
     | 
    
         
            +
                    div(class: "mt-8 sm:mx-auto sm:w-full sm:max-w-md") do
         
     | 
| 
      
 14 
     | 
    
         
            +
                      div(class: "bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10") do
         
     | 
| 
      
 15 
     | 
    
         
            +
                        p(class: "text-center text-skin-muted") { t("maquina.application.first_runs_header.description") }
         
     | 
| 
      
 16 
     | 
    
         
            +
                        form_with(model: @resource, url: first_run_path, method: :post, class: "space-y-6") do |form|
         
     | 
| 
      
 17 
     | 
    
         
            +
                          text_field(form, field_name: :email, required: true)
         
     | 
| 
      
 18 
     | 
    
         
            +
                          password_field(form, field_name: :password, required: true)
         
     | 
| 
      
 19 
     | 
    
         
            +
                          div do
         
     | 
| 
      
 20 
     | 
    
         
            +
                            form.submit t("helpers.submit.first_runs.create"), class: "flex w-full justify-center button button-accented"
         
     | 
| 
      
 21 
     | 
    
         
            +
                          end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        end
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <div class="flex min-h-full flex-col justify-center py-12 sm:px-6 lg:px-8">
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              <%= render Maquina::Application::SessionsHeader.new(brand_icon: brand_icon, translation_key: "maquina.application.first_runs_header") %>
         
     | 
| 
      
 4 
     | 
    
         
            +
              <%= render Maquina::FirstRuns::Form.new(@user) %>
         
     | 
| 
      
 5 
     | 
    
         
            +
            </div>
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Maquina
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Form
         
     | 
| 
      
 3 
     | 
    
         
            +
                include Phlex::Rails::Helpers::FormWith
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                protected
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def text_field(form, field_name:, required: false, label_class: "block label", input_class: "w-full block input", **options)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  div do
         
     | 
| 
      
 9 
     | 
    
         
            +
                    form.label field_name, class: label_class
         
     | 
| 
      
 10 
     | 
    
         
            +
                    div(class: "mt-1") do
         
     | 
| 
      
 11 
     | 
    
         
            +
                      form.text_field field_name, required: required, class: input_class,
         
     | 
| 
      
 12 
     | 
    
         
            +
                        **options.merge(field_attributes(field_name))
         
     | 
| 
      
 13 
     | 
    
         
            +
                      field_help(field_name)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def password_field(form, field_name:, required: false, label_class: "block label", input_class: "w-full block input", **options)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  div do
         
     | 
| 
      
 20 
     | 
    
         
            +
                    form.label field_name, class: label_class
         
     | 
| 
      
 21 
     | 
    
         
            +
                    div(class: "mt-1") do
         
     | 
| 
      
 22 
     | 
    
         
            +
                      form.password_field field_name, required: required, class: input_class,
         
     | 
| 
      
 23 
     | 
    
         
            +
                        **options.merge(field_attributes(field_name))
         
     | 
| 
      
 24 
     | 
    
         
            +
                      field_help(field_name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def field_attributes(field_name)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @scope ||= ""
         
     | 
| 
      
 31 
     | 
    
         
            +
                  {
         
     | 
| 
      
 32 
     | 
    
         
            +
                    maxlength: t("helpers.maxlength.#{@scope}.#{field_name}", default: t("helpers.maxlength.default")),
         
     | 
| 
      
 33 
     | 
    
         
            +
                    placeholder: t("placeholder.#{@scope}.#{field_name}", default: "")
         
     | 
| 
      
 34 
     | 
    
         
            +
                  }
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def field_help(field_name)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  help = t("help.#{@scope}.#{field_name}", default: "")
         
     | 
| 
      
 39 
     | 
    
         
            +
                  if help.present?
         
     | 
| 
      
 40 
     | 
    
         
            +
                    div(class: "mt-2 text-sm text-skin-dimmed") { help }
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -5,7 +5,7 @@ module Maquina 
     | 
|
| 
       5 
5 
     | 
    
         
             
                class MobileButton < Phlex::HTML
         
     | 
| 
       6 
6 
     | 
    
         
             
                  include ApplicationView
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                  def  
     | 
| 
      
 8 
     | 
    
         
            +
                  def view_template(&block)
         
     | 
| 
       9 
9 
     | 
    
         
             
                    div class: "flex items-center lg:hidden" do
         
     | 
| 
       10 
10 
     | 
    
         
             
                      button type: "button", class: "mobile-button", "aria-controls": "mobile-menu", "aria-expanded": false, "data-action": "mobile-menu#toggle" do
         
     | 
| 
       11 
11 
     | 
    
         
             
                        span(class: "sr-only") { "Open main menu" }
         
     | 
| 
         @@ -5,7 +5,7 @@ module Maquina 
     | 
|
| 
       5 
5 
     | 
    
         
             
                class Profile < Phlex::HTML
         
     | 
| 
       6 
6 
     | 
    
         
             
                  include ApplicationView
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                  def  
     | 
| 
      
 8 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       9 
9 
     | 
    
         
             
                    div class: "ml-4 relative flex-shrink-0", "data-controller": "popup-menu" do
         
     | 
| 
       10 
10 
     | 
    
         
             
                      render Maquina::Navbar::ProfileButton.new
         
     | 
| 
       11 
11 
     | 
    
         
             
                      render Maquina::Navbar::ProfileMenu.new
         
     | 
| 
         @@ -5,7 +5,7 @@ module Maquina 
     | 
|
| 
       5 
5 
     | 
    
         
             
                class ProfileButton < Phlex::HTML
         
     | 
| 
       6 
6 
     | 
    
         
             
                  include ApplicationView
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                  def  
     | 
| 
      
 8 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       9 
9 
     | 
    
         
             
                    div do
         
     | 
| 
       10 
10 
     | 
    
         
             
                      button type: "button", class: "bg-white rounded-full hidden lg:flex text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500", id: "user-menu-button", "aria-expanded": false, "aria-haspopup": true, "data-action": "popup-menu#toggleTransition" do
         
     | 
| 
       11 
11 
     | 
    
         
             
                        span(class: "sr-only") { "Open user menu" }
         
     | 
| 
         @@ -13,7 +13,7 @@ module Maquina 
     | 
|
| 
       13 
13 
     | 
    
         
             
                    @query = query
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  def  
     | 
| 
      
 16 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       17 
17 
     | 
    
         
             
                    div class: "flex-1 flex items-center justify-center px-2 lg:ml-6 lg:justify-end" do
         
     | 
| 
       18 
18 
     | 
    
         
             
                      div class: "max-w-lg w-full lg:max-w-xs" do
         
     | 
| 
       19 
19 
     | 
    
         
             
                        form_with(url: @url, method: :get, data: {controller: "submit-form"}) do |form|
         
     | 
| 
         @@ -10,11 +10,10 @@ module Maquina 
     | 
|
| 
       10 
10 
     | 
    
         
             
                    @resource = resource
         
     | 
| 
       11 
11 
     | 
    
         
             
                  end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                  def  
     | 
| 
      
 13 
     | 
    
         
            +
                  def view_template
         
     | 
| 
       14 
14 
     | 
    
         
             
                    div(class: "mt-8 sm:mx-auto sm:w-full sm:max-w-md") do
         
     | 
| 
       15 
15 
     | 
    
         
             
                      div(class: "bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10") do
         
     | 
| 
       16 
     | 
    
         
            -
                        form_with(url: sessions_path, method: :post, class: "space-y-6" 
     | 
| 
       17 
     | 
    
         
            -
                          form.hidden_field :return_to, value: @resource.return_to
         
     | 
| 
      
 16 
     | 
    
         
            +
                        form_with(url: sessions_path, method: :post, class: "space-y-6") do |form|
         
     | 
| 
       18 
17 
     | 
    
         
             
                          div do
         
     | 
| 
       19 
18 
     | 
    
         
             
                            form.label t("form.sessions.email"), for: :email, class: "block label"
         
     | 
| 
       20 
19 
     | 
    
         
             
                            div(class: "mt-1") do
         
     | 
| 
         @@ -31,7 +30,7 @@ module Maquina 
     | 
|
| 
       31 
30 
     | 
    
         
             
                            div do
         
     | 
| 
       32 
31 
     | 
    
         
             
                            end
         
     | 
| 
       33 
32 
     | 
    
         
             
                            div(class: "text-sm") do
         
     | 
| 
       34 
     | 
    
         
            -
                              a(href: "#", class: "link" 
     | 
| 
      
 33 
     | 
    
         
            +
                              a(href: "#", class: "link") { t("form.sessions.forgot_password") }
         
     | 
| 
       35 
34 
     | 
    
         
             
                            end
         
     | 
| 
       36 
35 
     | 
    
         
             
                          end
         
     | 
| 
       37 
36 
     | 
    
         
             
                          div do
         
     | 
| 
         @@ -2,8 +2,5 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
              <%= render Maquina::Application::SessionsHeader.new(brand_icon: brand_icon) %>
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
              <%=  
     | 
| 
       6 
     | 
    
         
            -
                <%= render Maquina::Sessions::Form.new(OpenStruct.new(params.slice(:email, :password, :return_to))) %>
         
     | 
| 
       7 
     | 
    
         
            -
              <% end %>
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
              <%= render Maquina::Sessions::Form.new(@user) %>
         
     | 
| 
       9 
6 
     | 
    
         
             
            </div>
         
     | 
    
        data/config/importmap.rb
    CHANGED
    
    | 
         @@ -1,12 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            pin "application" # , to: "maquina/application.js", preload: true
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            # Stimulus & Turbo
         
     | 
| 
       4 
     | 
    
         
            -
            pin "@hotwired/turbo-rails", to: "turbo.min.js" 
     | 
| 
       5 
     | 
    
         
            -
            pin "@hotwired/stimulus", to: "stimulus. 
     | 
| 
       6 
     | 
    
         
            -
            pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" 
     | 
| 
       7 
     | 
    
         
            -
            pin "stimulus-use", to: "https://ga.jspm.io/npm:stimulus-use@0.52.2/dist/index.js"
         
     | 
| 
      
 6 
     | 
    
         
            +
            pin "@hotwired/turbo-rails", to: "turbo.min.js"
         
     | 
| 
      
 7 
     | 
    
         
            +
            pin "@hotwired/stimulus", to: "@hotwired--stimulus.js" # @3.2.2
         
     | 
| 
      
 8 
     | 
    
         
            +
            pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
         
     | 
| 
      
 9 
     | 
    
         
            +
            pin "stimulus-use" # , to: "https://ga.jspm.io/npm:stimulus-use@0.52.2/dist/index.js"
         
     | 
| 
       8 
10 
     | 
    
         | 
| 
       9 
11 
     | 
    
         
             
            # Maquina entrypoint
         
     | 
| 
       10 
     | 
    
         
            -
            pin "application", to: "maquina/application.js", preload: true
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            pin_all_from Maquina::Engine.root.join("app/assets/javascripts/maquina/controllers"), under: "controllers", to: "maquina/controllers"
         
     | 
| 
      
 13 
     | 
    
         
            +
            pin_all_from Maquina::Engine.root.join("app/assets/javascripts/maquina/controllers"), under: "controllers" # , to: "maquina/controllers"
         
     |