Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement: return-to attribute for easier navigation #3598

Merged
merged 12 commits into from
Jan 28, 2025
Merged
4 changes: 4 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Ask a question
url: https://github.com/avo-hq/avo/discussions
about: Ask questions and discuss with other community members
- name: Priority Support
url: https://avohq.io/support
about: Get fast support from the authors of Avo
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ PATH
prop_initializer (>= 0.2.0)
turbo-rails (>= 2.0.0)
turbo_power (>= 0.6.0)
universalid
view_component (>= 3.7.0)
zeitwerk (>= 2.6.12)

Expand Down Expand Up @@ -161,6 +162,7 @@ GEM
bindex (0.8.1)
bootsnap (1.18.4)
msgpack (~> 1.2)
brotli (0.6.0)
builder (3.3.0)
bump (0.10.0)
bundler-integrity (1.0.9)
Expand All @@ -179,6 +181,9 @@ GEM
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.3.5)
config (5.5.2)
deep_merge (~> 1.2, >= 1.2.1)
ostruct
connection_pool (2.5.0)
countries (7.1.0)
unaccent (~> 0.3)
Expand All @@ -201,6 +206,7 @@ GEM
debug (1.10.0)
irb (~> 1.10)
reline (>= 0.3.8)
deep_merge (1.2.2)
derailed_benchmarks (2.1.2)
benchmark-ips (~> 2)
dead_end
Expand Down Expand Up @@ -418,6 +424,7 @@ GEM
nokogiri (1.18.1-x86_64-linux-gnu)
racc (~> 1.4)
orm_adapter (0.5.0)
ostruct (0.6.1)
pagy (9.3.3)
parallel (1.26.3)
parser (3.3.6.0)
Expand Down Expand Up @@ -648,6 +655,12 @@ GEM
concurrent-ruby (~> 1.0)
unaccent (0.4.0)
unicode-display_width (2.6.0)
universalid (0.1.7)
activesupport (>= 6.1)
brotli (>= 0.4)
config (>= 5.0)
msgpack (>= 1.7)
zeitwerk (>= 2.6)
uri (1.0.2)
useragent (0.16.11)
view_component (3.21.0)
Expand Down
1 change: 1 addition & 0 deletions app/assets/svgs/avo/square-kanban.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions app/components/avo/base_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ class Avo::BaseComponent < ViewComponent::Base
include Turbo::FramesHelper
include Avo::Concerns::FindAssociationField

delegate :e, to: :helpers
delegate :d, to: :helpers
delegate :main_app, to: :helpers
delegate :avo, to: :helpers

def has_with_trial(ability)
Avo.license.has_with_trial(ability)
end
Expand Down
5 changes: 5 additions & 0 deletions app/components/avo/button_component.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# frozen_string_literal: true

# A button/link can have the following settings:
# style: primary/outline/text/icon
# size: :xs :sm, :md, :lg, :xl
# color: :gray, :red, :green, :blue, or any other tailwind color
# icon: "heroicons/outline/paperclip" as specified in the docs (https://docs.avohq.io/3.0/icons.html)
class Avo::ButtonComponent < Avo::BaseComponent
prop :path, kind: :positional
prop :size, default: :md
Expand Down
1 change: 1 addition & 0 deletions app/components/avo/referrer_params_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
<%= hidden_field_tag :via_record_id, params[:via_record_id] if params[:via_record_id] %>
<%= hidden_field_tag :via_relation, params[:via_relation] if params[:via_relation] %>
<%= hidden_field_tag :via_belongs_to_resource_class, params[:via_belongs_to_resource_class] if params[:via_belongs_to_resource_class] %>
<%= hidden_field_tag :return_to, params[:return_to] if params[:return_to].present? %>
<%= hidden_field_tag :referrer, @back_path if params[:via_resource_class] %>
3 changes: 3 additions & 0 deletions app/components/avo/views/resource_edit_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def title
end

def back_path
# The `return_to` param takes precedence over anything else.
return params[:return_to] if params[:return_to].present?

return if via_belongs_to?
return resource_view_path if via_resource?
return resources_path if via_index?
Expand Down
3 changes: 3 additions & 0 deletions app/components/avo/views/resource_index_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ def can_render_scopes?
end

def back_path
# The `return_to` param takes precedence over anything else.
return params[:return_to] if params[:return_to].present?

# Show Go Back link only when association page is opened
# as a standalone page
if @reflection.present? && !helpers.turbo_frame_request?
Expand Down
6 changes: 6 additions & 0 deletions app/components/avo/views/resource_show_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def title
end

def back_path
# The `return_to` param takes precedence over anything else.
return params[:return_to] if params[:return_to].present?

if via_resource?
helpers.resource_path(resource: association_resource, resource_id: params[:via_record_id])
else
Expand All @@ -50,6 +53,9 @@ def edit_path
{}
end

# Pass the return_to param to the edit path so the chain of navigation is kept.
args[:return_to] = params[:return_to] if params[:return_to].present?

helpers.edit_resource_path(record: @resource.record, resource: @resource, **args)
end

Expand Down
23 changes: 11 additions & 12 deletions app/controllers/avo/base_application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ class BaseApplicationController < ::ActionController::Base
include Avo::Concerns::FindAssociationField

protect_from_forgery with: :exception
before_action :decode_params
around_action :set_avo_locale
around_action :set_force_locale, if: -> { params[:force_locale].present? }
before_action :init_app
before_action :set_active_storage_current_host
before_action :set_resource_name
before_action :_authenticate!
before_action :set_authorization
before_action :set_container_classes
before_action :add_initial_breadcrumbs
before_action :set_view
before_action :set_sidebar_open
Expand All @@ -30,7 +30,7 @@ class BaseApplicationController < ::ActionController::Base
rescue_from Avo::NotAuthorizedError, with: :render_unauthorized
rescue_from ActiveRecord::RecordInvalid, with: :exception_logger

helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path, :preview_resource_path
helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path, :preview_resource_path, :e
add_flash_types :info, :warning, :success, :error

def exception_logger(exception)
Expand Down Expand Up @@ -255,16 +255,8 @@ def set_authorization
end
end

def set_container_classes
contain = true

if Avo.configuration.full_width_container
contain = false
elsif Avo.configuration.full_width_index_view && action_name.to_sym == :index && self.class.superclass.to_s == "Avo::ResourcesController"
contain = false
end

@container_classes = contain ? "2xl:container 2xl:mx-auto" : ""
def mark_container_as_full_width
@container_full_width = true
end

def add_initial_breadcrumbs
Expand Down Expand Up @@ -339,5 +331,12 @@ def authenticate_developer_or_admin!
def raise_404
raise ActionController::RoutingError.new "No route matches"
end

def decode_params
if params[:return_to].present?
params[:raw_return_to] = params[:return_to]
params[:return_to] = d(params[:return_to])
end
end
end
end
11 changes: 8 additions & 3 deletions app/controllers/avo/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ def update_fail_message
end

def after_update_path
# The `return_to` param takes precedence over anything else.
return params[:return_to] if params[:return_to].present?
return params[:referrer] if params[:referrer].present?

redirect_path_from_resource_option(:after_update_path) || resource_view_response_path
Expand Down Expand Up @@ -554,12 +556,15 @@ def after_destroy_path
def redirect_path_from_resource_option(action = :after_update_path)
return nil if @resource.class.send(action).blank?

extra_args = {}
extra_args[:return_to] = params[:return_to] if params[:return_to].present?

if @resource.class.send(action) == :index
resources_path(resource: @resource)
resources_path(resource: @resource, **extra_args)
elsif @resource.class.send(action) == :edit || Avo.configuration.resource_default_view.edit?
edit_resource_path(resource: @resource, record: @resource.record)
edit_resource_path(resource: @resource, record: @resource.record, **extra_args)
else
resource_path(record: @record, resource: @resource)
resource_path(record: @record, resource: @resource, **extra_args)
end
end

Expand Down
28 changes: 28 additions & 0 deletions app/helpers/avo/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,34 @@ def possibly_rails_authentication?
defined?(Authentication) && Authentication.private_instance_methods.include?(:require_authentication) && Authentication.private_instance_methods.include?(:authenticated?)
end

def container_classes
adrianthedev marked this conversation as resolved.
Show resolved Hide resolved
adrianthedev marked this conversation as resolved.
Show resolved Hide resolved
container_classes = "2xl:container 2xl:mx-auto"

contain_is_full_width = if @container_full_width.present?
@container_full_width
elsif Avo.configuration.full_width_container
true
elsif Avo.configuration.full_width_index_view && action_name.to_sym == :index && self.class.superclass.to_s == "Avo::ResourcesController"
true
else
false
end

contain_is_full_width ? "" : container_classes
end

# encode params
def e(value)
URI::UID.build(value).payload
end

# decode params
def d(value)
URI::UID.from_payload(value).decode
rescue
value
end

private

# Taken from the original library
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/avo/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<%= render Avo::SidebarComponent.new sidebar_open: false, for_mobile: true %>
</div>
<div class="main-content-area flex-1 flex flex-col min-h-full max-w-full">
<div class="content p-4 lg:p-6 flex-1 flex flex-col justify-between items-stretch <%= @container_classes %>">
<div class="content p-4 lg:p-6 flex-1 flex flex-col justify-between items-stretch <%= container_classes %>">
<%= render partial: "avo/partials/custom_tools_alert" %>
<div class="flex flex-1 flex-col justify-between items-stretch space-y-8">
<%= yield.force_encoding("UTF-8") %>
Expand Down
1 change: 1 addition & 0 deletions avo.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@ Gem::Specification.new do |spec|
spec.add_dependency "docile"
spec.add_dependency "inline_svg"
spec.add_dependency "prop_initializer", ">= 0.2.0"
spec.add_dependency "universalid"
end
13 changes: 13 additions & 0 deletions gemfiles/rails_6.1_ruby_3.1.4.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PATH
prop_initializer (>= 0.2.0)
turbo-rails (>= 2.0.0)
turbo_power (>= 0.6.0)
universalid
view_component (>= 3.7.0)
zeitwerk (>= 2.6.12)

Expand Down Expand Up @@ -148,6 +149,7 @@ GEM
bindex (0.8.1)
bootsnap (1.18.4)
msgpack (~> 1.2)
brotli (0.6.0)
builder (3.3.0)
bump (0.10.0)
bundler-integrity (1.0.9)
Expand All @@ -166,6 +168,9 @@ GEM
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.3.4)
config (5.5.2)
deep_merge (~> 1.2, >= 1.2.1)
ostruct
connection_pool (2.5.0)
countries (7.1.0)
unaccent (~> 0.3)
Expand All @@ -188,6 +193,7 @@ GEM
debug (1.10.0)
irb (~> 1.10)
reline (>= 0.3.8)
deep_merge (1.2.2)
derailed_benchmarks (2.1.2)
benchmark-ips (~> 2)
dead_end
Expand Down Expand Up @@ -404,6 +410,7 @@ GEM
nokogiri (1.18.1-x86_64-linux-gnu)
racc (~> 1.4)
orm_adapter (0.5.0)
ostruct (0.6.1)
pagy (9.3.3)
parallel (1.26.3)
parser (3.3.6.0)
Expand Down Expand Up @@ -623,6 +630,12 @@ GEM
concurrent-ruby (~> 1.0)
unaccent (0.4.0)
unicode-display_width (2.6.0)
universalid (0.1.7)
activesupport (>= 6.1)
brotli (>= 0.4)
config (>= 5.0)
msgpack (>= 1.7)
zeitwerk (>= 2.6)
uri (1.0.2)
view_component (3.21.0)
activesupport (>= 5.2.0, < 8.1)
Expand Down
13 changes: 13 additions & 0 deletions gemfiles/rails_6.1_ruby_3.3.0.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PATH
prop_initializer (>= 0.2.0)
turbo-rails (>= 2.0.0)
turbo_power (>= 0.6.0)
universalid
view_component (>= 3.7.0)
zeitwerk (>= 2.6.12)

Expand Down Expand Up @@ -148,6 +149,7 @@ GEM
bindex (0.8.1)
bootsnap (1.18.4)
msgpack (~> 1.2)
brotli (0.6.0)
builder (3.3.0)
bump (0.10.0)
bundler-integrity (1.0.9)
Expand All @@ -166,6 +168,9 @@ GEM
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.3.4)
config (5.5.2)
deep_merge (~> 1.2, >= 1.2.1)
ostruct
connection_pool (2.5.0)
countries (7.1.0)
unaccent (~> 0.3)
Expand All @@ -188,6 +193,7 @@ GEM
debug (1.10.0)
irb (~> 1.10)
reline (>= 0.3.8)
deep_merge (1.2.2)
derailed_benchmarks (2.1.2)
benchmark-ips (~> 2)
dead_end
Expand Down Expand Up @@ -376,6 +382,7 @@ GEM
nokogiri (1.18.1-x86_64-linux-gnu)
racc (~> 1.4)
orm_adapter (0.5.0)
ostruct (0.6.1)
pagy (9.3.3)
parallel (1.26.3)
parser (3.2.2.4)
Expand Down Expand Up @@ -594,6 +601,12 @@ GEM
concurrent-ruby (~> 1.0)
unaccent (0.4.0)
unicode-display_width (2.6.0)
universalid (0.1.7)
activesupport (>= 6.1)
brotli (>= 0.4)
config (>= 5.0)
msgpack (>= 1.7)
zeitwerk (>= 2.6)
uri (1.0.2)
view_component (3.21.0)
activesupport (>= 5.2.0, < 8.1)
Expand Down
Loading
Loading