diff --git a/app/components/avo/fields/common/files/view_type/grid_item_component.html.erb b/app/components/avo/fields/common/files/view_type/grid_item_component.html.erb index cb5910355d..83883f32c6 100644 --- a/app/components/avo/fields/common/files/view_type/grid_item_component.html.erb +++ b/app/components/avo/fields/common/files/view_type/grid_item_component.html.erb @@ -7,11 +7,11 @@ <% elsif is_video? %> <%= video_tag(helpers.main_app.url_for(file), controls: true, preload: false, class: 'w-full') %> <% else %> -
+ <%= content_tag file.representable? ? :a : :div, **document_arguments do %>
<%= helpers.svg "heroicons/outline/document-text", class: 'h-10 text-gray-600 mb-2' %>
-
+ <% end %> <% end %> <% if @field.display_filename %> <%= file.filename %> diff --git a/app/components/avo/fields/common/files/view_type/grid_item_component.rb b/app/components/avo/fields/common/files/view_type/grid_item_component.rb index 013596eaac..28540e092e 100644 --- a/app/components/avo/fields/common/files/view_type/grid_item_component.rb +++ b/app/components/avo/fields/common/files/view_type/grid_item_component.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Avo::Fields::Common::Files::ViewType::GridItemComponent < Avo::BaseComponent + include Avo::Fields::Concerns::FileAuthorization + prop :field prop :resource prop :file @@ -45,4 +47,27 @@ def record_persisted? ActiveStorage::Blob.destroy(file.blob_id) if file.blob_id.present? false end + + def document_arguments + args = { + class: class_names( + "relative flex flex-col justify-evenly items-center px-2 rounded-lg border bg-white border-gray-500 min-h-24", + { + "hover:bg-gray-100 transition": file.representable? + } + ) + } + + if file.representable? && can_download_file? + args.merge!( + { + href: helpers.main_app.url_for(file), + target: "_blank", + rel: "noopener noreferrer" + } + ) + end + + args + end end diff --git a/spec/dummy/app/assets/csvs/sample.csv b/spec/dummy/app/assets/csvs/sample.csv new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/dummy/app/assets/pdfs/cv_sample.pdf b/spec/dummy/app/assets/pdfs/cv_sample.pdf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/system/avo/open_field_attachment_spec.rb b/spec/system/avo/open_field_attachment_spec.rb new file mode 100644 index 0000000000..5c2c6974e8 --- /dev/null +++ b/spec/system/avo/open_field_attachment_spec.rb @@ -0,0 +1,57 @@ +require "rails_helper" + +RSpec.describe "OpenFieldAttachment", type: :system do + let!(:user) { User.first } + let!(:cv_file) { Rails.root.join("app", "assets", "pdfs", "cv_sample.pdf") } + let!(:csv_file) { Rails.root.join("app", "assets", "csvs", "sample.csv") } + let(:path) { "/admin/resources/field_discovery_users/#{user.slug}" } + + context "with PDF attachment" do + before do + user.cv.attach(io: File.open(cv_file), filename: "cv_sample.pdf", content_type: "application/pdf") + end + + it "opens attachment in new window without download" do + test_open_PDF_attachment(path) + end + end + + context "with CSV attachment" do + before do + user.cv.attach(io: File.open(csv_file), filename: "sample.csv", content_type: "application/csv") + end + + it "can not open or download attachment in new window" do + test_open_CSV_attachment(path) + end + end + + def test_open_PDF_attachment(path) + visit path + + link = find('a[rel="noopener noreferrer"][target="_blank"]', visible: :all) + + expect(link).to be_present + expect(link[:target]).to eq("_blank") + expect(link[:rel]).to eq("noopener noreferrer") + link.click + + expect(page.driver.browser.current_url).not_to include("download") + expect(page.driver.browser.window_handles.length).to eq 2 + end + + def test_open_CSV_attachment(path) + visit path + + div = find('span[title="' + csv_file.basename.to_s + '"]').find(:xpath, './ancestor::div[@class="flex flex-col h-full"]') + + link = div.find("a") + expect(link[:rel]).to eq("") + expect(link[:target]).to eq("") + + div.find('svg[data-slot="icon"]').find(:xpath, "./ancestor::a").click + + expect(page.driver.browser.current_url).not_to include("download") + expect(page.driver.browser.window_handles.length).to eq 1 + end +end