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