diff --git a/app/components/avo/items/panel_component.rb b/app/components/avo/items/panel_component.rb
index 5e0dc8ce78..f8a17cc974 100644
--- a/app/components/avo/items/panel_component.rb
+++ b/app/components/avo/items/panel_component.rb
@@ -34,7 +34,8 @@ def args
index: 0,
data: {panel_id: "main"},
cover_photo: @resource.cover_photo,
- profile_photo: @resource.profile_photo
+ profile_photo: @resource.profile_photo,
+ external_link: @resource.get_external_link
}
else
{name: @item.name, description: @item.description, index: @index}
diff --git a/app/components/avo/panel_component.html.erb b/app/components/avo/panel_component.html.erb
index 63da39b304..a289ee8bc7 100644
--- a/app/components/avo/panel_component.html.erb
+++ b/app/components/avo/panel_component.html.erb
@@ -4,7 +4,8 @@
name: @name,
description: @description,
display_breadcrumbs: @display_breadcrumbs,
- profile_photo: @profile_photo
+ profile_photo: @profile_photo,
+ external_link: @external_link
) do |header| %>
<% if name_slot.present? %>
<% header.with_name_slot do %>
diff --git a/app/components/avo/panel_component.rb b/app/components/avo/panel_component.rb
index 6c865563ea..c725d49b47 100644
--- a/app/components/avo/panel_component.rb
+++ b/app/components/avo/panel_component.rb
@@ -28,6 +28,7 @@ class Avo::PanelComponent < Avo::BaseComponent
def after_initialize
@name = @args.dig(:name) || @args.dig(:title)
end
+ prop :external_link
def classes
class_names(@classes, "has-cover-photo": @cover_photo.present?, "has-profile-photo": @profile_photo.present?)
diff --git a/app/components/avo/panel_header_component.html.erb b/app/components/avo/panel_header_component.html.erb
index 4f1b08fd02..7ff8ad9938 100644
--- a/app/components/avo/panel_header_component.html.erb
+++ b/app/components/avo/panel_header_component.html.erb
@@ -12,7 +12,15 @@
<% if name_slot? %>
<%= name_slot %>
<% else %>
- <%= render Avo::PanelNameComponent.new name: @name %>
+ <%= render Avo::PanelNameComponent.new name: @name do |panel_name_component| %>
+ <% panel_name_component.with_body do %>
+ <% if @external_link.present? %>
+ <%= link_to @external_link, class: "text-gray-600 hover:text-gray-900 mt-1", title: helpers.t("avo.visit_record_on_external_path"), data: {tippy: :tooltip}, target: :_blank do %>
+ <%= svg "heroicons/outline/arrow-top-right-on-square", class: "ml-2 text-2xl h-4" %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
<% end %>
<% if @description.present? %>
diff --git a/app/components/avo/panel_header_component.rb b/app/components/avo/panel_header_component.rb
index 5155c86a9a..168cc60c2f 100644
--- a/app/components/avo/panel_header_component.rb
+++ b/app/components/avo/panel_header_component.rb
@@ -7,6 +7,7 @@ class Avo::PanelHeaderComponent < Avo::BaseComponent
renders_one :tools
prop :name
+ prop :external_link
prop :description
prop :display_breadcrumbs, default: false
prop :profile_photo
diff --git a/lib/avo/resources/base.rb b/lib/avo/resources/base.rb
index b8b8cae16e..a215aa80f3 100644
--- a/lib/avo/resources/base.rb
+++ b/lib/avo/resources/base.rb
@@ -80,6 +80,7 @@ def current_user
class_attribute :default_sort_column, default: :created_at
class_attribute :default_sort_direction, default: :desc
class_attribute :controls_placement, default: nil
+ class_attribute :external_link, default: nil
# EXTRACT:
class_attribute :ordering
@@ -644,6 +645,12 @@ def resolve_component(original_component)
custom_components.dig(original_component.to_s)&.to_s&.safe_constantize || original_component
end
+ def get_external_link
+ return unless record.persisted?
+
+ Avo::ExecutionContext.new(target: external_link, resource: self, record: record).handle
+ end
+
private
def flatten_keys(array)
diff --git a/lib/generators/avo/templates/locales/avo.ar.yml b/lib/generators/avo/templates/locales/avo.ar.yml
index dfe34d7c6c..9ad4d4f07e 100644
--- a/lib/generators/avo/templates/locales/avo.ar.yml
+++ b/lib/generators/avo/templates/locales/avo.ar.yml
@@ -122,6 +122,7 @@ ar:
undo: تراجع
view: عرض
view_item: عرض %{item}
+ visit_record_on_external_path: زيارة السجل على الرابط الخارجي
was_successfully_created: تم إنشاؤه بنجاح
was_successfully_updated: تم تحديثه بنجاح
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.de.yml b/lib/generators/avo/templates/locales/avo.de.yml
index c23d1c5ed9..a3b6a41f92 100644
--- a/lib/generators/avo/templates/locales/avo.de.yml
+++ b/lib/generators/avo/templates/locales/avo.de.yml
@@ -112,6 +112,7 @@ de:
undo: Rückgängig machen
view: Anzeigen
view_item: "%{item} anzeigen"
+ visit_record_on_external_path: Datensatz über externen Link besuchen
was_successfully_created: wurde erfolgreich erstellt
was_successfully_updated: wurde erfolgreich aktualisiert
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.en.yml b/lib/generators/avo/templates/locales/avo.en.yml
index cd57bc4e4c..f2f806ae8f 100644
--- a/lib/generators/avo/templates/locales/avo.en.yml
+++ b/lib/generators/avo/templates/locales/avo.en.yml
@@ -112,6 +112,7 @@ en:
undo: undo
view: View
view_item: view %{item}
+ visit_record_on_external_path: Visit record on external path
was_successfully_created: was successfully created
was_successfully_updated: was successfully updated
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.es.yml b/lib/generators/avo/templates/locales/avo.es.yml
index 037506d53d..d987ba069f 100644
--- a/lib/generators/avo/templates/locales/avo.es.yml
+++ b/lib/generators/avo/templates/locales/avo.es.yml
@@ -114,6 +114,7 @@ es:
undo: deshacer
view: Vista
view_item: ver %{item}
+ visit_record_on_external_path: Visitar registro en enlace externo
was_successfully_created: se ha creado con éxito
was_successfully_updated: se ha actualizado con éxito
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.fr.yml b/lib/generators/avo/templates/locales/avo.fr.yml
index ec5971b7c6..e19a71dc01 100644
--- a/lib/generators/avo/templates/locales/avo.fr.yml
+++ b/lib/generators/avo/templates/locales/avo.fr.yml
@@ -114,6 +114,7 @@ fr:
undo: annuler
view: Vue
view_item: voir %{item}
+ visit_record_on_external_path: Consulter l'enregistrement via un lien externe
was_successfully_created: a été créé avec succès
was_successfully_updated: a été mis à jour avec succès
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.it.yml b/lib/generators/avo/templates/locales/avo.it.yml
index ae336b507e..b16eedbf07 100644
--- a/lib/generators/avo/templates/locales/avo.it.yml
+++ b/lib/generators/avo/templates/locales/avo.it.yml
@@ -112,6 +112,7 @@ it:
undo: Annulla
view: Visualizza
view_item: Visualizza %{item}
+ visit_record_on_external_path: Visita il record tramite link esterno
was_successfully_created: è stato creato con successo
was_successfully_updated: è stato aggiornato con successo
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.ja.yml b/lib/generators/avo/templates/locales/avo.ja.yml
index 205f025e4b..e1554783db 100644
--- a/lib/generators/avo/templates/locales/avo.ja.yml
+++ b/lib/generators/avo/templates/locales/avo.ja.yml
@@ -114,6 +114,7 @@ ja:
undo: 元に戻す
view: ビュー
view_item: "%{item}を表示"
+ visit_record_on_external_path: 外部リンクで記録を確認する
was_successfully_created: は正常に作成されました
was_successfully_updated: は正常に更新されました
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.nb.yml b/lib/generators/avo/templates/locales/avo.nb.yml
index 01be9b6edb..0725e55469 100644
--- a/lib/generators/avo/templates/locales/avo.nb.yml
+++ b/lib/generators/avo/templates/locales/avo.nb.yml
@@ -114,6 +114,7 @@ nb:
undo: angre
view: Vis
view_item: vis %{item}
+ visit_record_on_external_path: Besøk posten via en ekstern lenke
was_successfully_created: ble opprettet
was_successfully_updated: ble oppdatert
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.nl.yml b/lib/generators/avo/templates/locales/avo.nl.yml
index b2dbf037aa..f971622e38 100644
--- a/lib/generators/avo/templates/locales/avo.nl.yml
+++ b/lib/generators/avo/templates/locales/avo.nl.yml
@@ -112,6 +112,7 @@ nl:
undo: Ongedaan maken
view: Bekijken
view_item: "%{item} bekijken"
+ visit_record_on_external_path: Bezoek record via een externe link
was_successfully_created: is succesvol aangemaakt
was_successfully_updated: is succesvol bijgewerkt
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.nn.yml b/lib/generators/avo/templates/locales/avo.nn.yml
index 0bbdd68298..76c4c5f9d7 100644
--- a/lib/generators/avo/templates/locales/avo.nn.yml
+++ b/lib/generators/avo/templates/locales/avo.nn.yml
@@ -114,6 +114,7 @@ nn:
undo: angre
view: Vis
view_item: vis %{item}
+ visit_record_on_external_path: Besøk posten via ein ekstern lenke
was_successfully_created: vart oppretta
was_successfully_updated: vart oppdatert
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.pl.yml b/lib/generators/avo/templates/locales/avo.pl.yml
index 89c0f07d31..8b691aa3e8 100644
--- a/lib/generators/avo/templates/locales/avo.pl.yml
+++ b/lib/generators/avo/templates/locales/avo.pl.yml
@@ -114,6 +114,7 @@ pl:
undo: Cofnij
view: Widok
view_item: Wyświetl %{item}
+ visit_record_on_external_path: Odwiedź rekord za pomocą zewnętrznego linku
was_successfully_created: został pomyślnie utworzony
was_successfully_updated: został pomyślnie zaktualizowany
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.pt-BR.yml b/lib/generators/avo/templates/locales/avo.pt-BR.yml
index 9d278e3d87..e10d0b34a7 100644
--- a/lib/generators/avo/templates/locales/avo.pt-BR.yml
+++ b/lib/generators/avo/templates/locales/avo.pt-BR.yml
@@ -114,6 +114,7 @@ pt-BR:
undo: desfazer
view: Visualizar
view_item: visualizar %{item}
+ visit_record_on_external_path: Visitar registro através de link externo
was_successfully_created: foi criado com sucesso
was_successfully_updated: foi atualizado com sucesso
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.pt.yml b/lib/generators/avo/templates/locales/avo.pt.yml
index 872ee3350c..4601abcbf1 100644
--- a/lib/generators/avo/templates/locales/avo.pt.yml
+++ b/lib/generators/avo/templates/locales/avo.pt.yml
@@ -114,6 +114,7 @@ pt:
undo: desfazer
view: Ver
view_item: ver %{item}
+ visit_record_on_external_path: Visitar registro através de link externo
was_successfully_created: foi criado com sucesso
was_successfully_updated: foi atualizado com sucesso
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.ro.yml b/lib/generators/avo/templates/locales/avo.ro.yml
index 1c314ffe85..311d0c3c71 100644
--- a/lib/generators/avo/templates/locales/avo.ro.yml
+++ b/lib/generators/avo/templates/locales/avo.ro.yml
@@ -116,6 +116,7 @@ ro:
undo: Anulează
view: vezi
view_item: vezi %{item}
+ visit_record_on_external_path: Vizitați înregistrarea printr-un link extern
was_successfully_created: a fost creat
was_successfully_updated: a fost actualizat
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.ru.yml b/lib/generators/avo/templates/locales/avo.ru.yml
index f13890fa0d..49a038ad26 100644
--- a/lib/generators/avo/templates/locales/avo.ru.yml
+++ b/lib/generators/avo/templates/locales/avo.ru.yml
@@ -114,6 +114,7 @@ ru:
undo: Отменить
view: Просмотр
view_item: Просмотр %{item}
+ visit_record_on_external_path: Перейти к записи через внешнюю ссылку
was_successfully_created: успешно создана
was_successfully_updated: успешно обновлена
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.tr.yml b/lib/generators/avo/templates/locales/avo.tr.yml
index e4fe7bc9d1..8b06189f7d 100644
--- a/lib/generators/avo/templates/locales/avo.tr.yml
+++ b/lib/generators/avo/templates/locales/avo.tr.yml
@@ -114,6 +114,7 @@ tr:
undo: geri al
view: Görünüm
view_item: "%{item} öğresini görüntüle"
+ visit_record_on_external_path: Harici bağlantı yoluyla kaydı ziyaret et
was_successfully_created: başarıyla oluşturuldu
was_successfully_updated: başarıyla güncellendi
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.uk.yml b/lib/generators/avo/templates/locales/avo.uk.yml
index ec5d7767d7..2d32e12308 100644
--- a/lib/generators/avo/templates/locales/avo.uk.yml
+++ b/lib/generators/avo/templates/locales/avo.uk.yml
@@ -114,6 +114,7 @@ uk:
undo: Скасувати
view: Перегляд
view_item: Перегляд %{item}
+ visit_record_on_external_path: Перейти до запису через зовнішнє посилання
was_successfully_created: успішно створено
was_successfully_updated: успішно оновлено
x_items_more:
diff --git a/lib/generators/avo/templates/locales/avo.zh.yml b/lib/generators/avo/templates/locales/avo.zh.yml
index a6a0233e08..99258cc63b 100644
--- a/lib/generators/avo/templates/locales/avo.zh.yml
+++ b/lib/generators/avo/templates/locales/avo.zh.yml
@@ -112,6 +112,7 @@ zh:
undo: 撤销
view: 查看
view_item: 查看 %{item}
+ visit_record_on_external_path: 通过外部链接访问记录
was_successfully_created: 创建成功
was_successfully_updated: 更新成功
x_items_more:
diff --git a/spec/dummy/app/avo/resources/post.rb b/spec/dummy/app/avo/resources/post.rb
index e99173b743..c7a89c8e55 100644
--- a/spec/dummy/app/avo/resources/post.rb
+++ b/spec/dummy/app/avo/resources/post.rb
@@ -28,6 +28,10 @@ class Avo::Resources::Post < Avo::BaseResource
end
}
self.view_types = [:grid, :table]
+ # Show a link to the post outside Avo
+ self.external_link = -> {
+ main_app.post_path(record)
+ }
def fields
field :id, as: :id
diff --git a/spec/dummy/app/controllers/posts_controller.rb b/spec/dummy/app/controllers/posts_controller.rb
new file mode 100644
index 0000000000..05e7a9f25f
--- /dev/null
+++ b/spec/dummy/app/controllers/posts_controller.rb
@@ -0,0 +1,9 @@
+class PostsController < ApplicationController
+ def index
+ @posts = Post.all
+ end
+
+ def show
+ @post = Post.find(params[:id])
+ end
+end
diff --git a/spec/dummy/app/views/posts/index.html.erb b/spec/dummy/app/views/posts/index.html.erb
new file mode 100644
index 0000000000..7141919097
--- /dev/null
+++ b/spec/dummy/app/views/posts/index.html.erb
@@ -0,0 +1,4 @@
+
Posts#index
+
Find me in app/views/posts/index.html.erb
+
+<%= @posts.count %>
diff --git a/spec/dummy/app/views/posts/show.html.erb b/spec/dummy/app/views/posts/show.html.erb
new file mode 100644
index 0000000000..445201d996
--- /dev/null
+++ b/spec/dummy/app/views/posts/show.html.erb
@@ -0,0 +1,4 @@
+
Posts#show
+
Find me in app/views/posts/show.html.erb
+
+<%= @post.inspect %>
diff --git a/spec/dummy/config/locales/avo.en.yml b/spec/dummy/config/locales/avo.en.yml
index b0527a658f..94c1036381 100644
--- a/spec/dummy/config/locales/avo.en.yml
+++ b/spec/dummy/config/locales/avo.en.yml
@@ -110,6 +110,7 @@ en:
undo: undo
view: View
view_item: view %{item}
+ visit_record_on_external_path: Visit record on external path
was_successfully_created: was successfully created
was_successfully_updated: was successfully updated
x_items_more:
diff --git a/spec/dummy/config/routes.rb b/spec/dummy/config/routes.rb
index 29dcb07d2b..1dad6d2d4e 100644
--- a/spec/dummy/config/routes.rb
+++ b/spec/dummy/config/routes.rb
@@ -5,6 +5,8 @@
get "hey", to: "home#index"
+ resources :posts
+
authenticate :user, ->(user) { user.is_admin? } do
scope :admin do
get "custom_tool", to: "avo/tools#custom_tool", as: :custom_tool
diff --git a/spec/features/avo/external_link_spec.rb b/spec/features/avo/external_link_spec.rb
new file mode 100644
index 0000000000..0dac2bf7eb
--- /dev/null
+++ b/spec/features/avo/external_link_spec.rb
@@ -0,0 +1,25 @@
+require "rails_helper"
+
+RSpec.feature "external_link", type: :feature do
+ let!(:post) { create :post }
+
+ describe "external_link" do
+ it "on show" do
+ visit avo.resources_post_path(post)
+
+ find("[target='_blank'][href='/posts/#{post.to_param}']").click
+
+ expect(current_path).to eq "/posts/#{post.to_param}"
+ expect(page).to have_text("Find me in app/views/posts/show.html.erb")
+ end
+
+ it "on edit" do
+ visit avo.edit_resources_post_path(post)
+
+ find("[target='_blank'][href='/posts/#{post.to_param}']").click
+
+ expect(current_path).to eq "/posts/#{post.to_param}"
+ expect(page).to have_text("Find me in app/views/posts/show.html.erb")
+ end
+ end
+end