-
-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: media library/gallery (#3561)
* feature: media library * renamve components * make it work for trix and rhino too * add request.js * wip * wip * wip * wip * wip * wip * can upload * add configuration * add helpers * add authorization * fix update and destroy * wip * wip * wip * wip * Potential fix for code scanning alert no. 43: DOM text reinterpreted as HTML Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * properly escape the filename * lint * 18n-tasks translate-missing * revert unique_id for trix input * npx update-browserslist-db@latest * fix unique_selector --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Paul Bob <[email protected]> Co-authored-by: Paul Bob <[email protected]>
- Loading branch information
1 parent
ba6578f
commit 8ed64be
Showing
60 changed files
with
915 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 3 additions & 7 deletions
10
app/components/avo/fields/tiptap_field/show_component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 3 additions & 7 deletions
10
app/components/avo/fields/trix_field/show_component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
app/components/avo/media_library/item_details_component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<div class="relative flex flex-col w-full max @container/details"> | ||
<%= link_to helpers.svg('heroicons/outline/x-mark', class: "size-6"), helpers.avo.media_library_index_path, | ||
class: "absolute z-10 inset-auto right-0 top-0 mt-2 mr-2 block bg-white p-1 rounded-lg text-slate-600 hover:text-slate-900", | ||
title: t('avo.close'), | ||
data: { | ||
tippy: :tooltip, | ||
} %> | ||
<div class="flex flex-1 flex-row w-full"> | ||
<div class="flex flex-col justify-center w-1/2 @3xl/details:w-2/3 p-4 gap-2"> | ||
<% if @blob.image? %> | ||
<%= image_tag helpers.main_app.url_for(@blob), class: "max-w-full rounded-lg max-h-xl", loading: :lazy %> | ||
<% elsif @blob.audio? %> | ||
<%= audio_tag(helpers.main_app.url_for(@blob), controls: true, preload: false, class: 'w-full') %> | ||
<% elsif @blob.video? %> | ||
<%= video_tag(helpers.main_app.url_for(@blob), controls: true, preload: false, class: 'w-full') %> | ||
<% else %> | ||
<div class="relative h-full flex flex-col justify-center items-center w-full bg-slate-100"> | ||
<%= helpers.svg "heroicons/outline/document-text", class: 'h-10 text-gray-600 mb-2' %> | ||
</div> | ||
<% end %> | ||
<div class="flex justify-center w-full text-sm gap-4"> | ||
<%= link_to "Download", helpers.main_app.url_for(@blob), download: true %> | ||
<%= link_to "Copy URL to clipboard", helpers.main_app.url_for(@blob), data: {controller: "copy-to-clipboard", text: helpers.main_app.url_for(@blob), action: "click->copy-to-clipboard#copy"} %> | ||
<%= link_to "Delete", helpers.avo.media_library_path(@blob), class: "text-red-500", data: {turbo_confirm: "Are you sure you want to destroy this attachment?", turbo_method: :delete} %> | ||
</div> | ||
</div> | ||
<div class="flex flex-col w-1/2 @3xl/details:w-1/3 border-l"> | ||
<%= render partial: "avo/media_library/information", locals: {blob: @blob} %> | ||
<%= render partial: "avo/media_library/form", locals: {blob: @blob} %> | ||
</div> | ||
</div> | ||
</div> |
12 changes: 12 additions & 0 deletions
12
app/components/avo/media_library/item_details_component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# frozen_string_literal: true | ||
|
||
module Avo | ||
module MediaLibrary | ||
class ItemDetailsComponent < Avo::BaseComponent | ||
include Turbo::FramesHelper | ||
include Avo::ApplicationHelper | ||
|
||
prop :blob | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<%= render Avo::PanelComponent.new title: t("avo.media_library.title"), | ||
data: { | ||
controller: 'media-library', | ||
media_library_controller_selector_value: params[:controller_selector], | ||
media_library_controller_name_value: params[:controller_name], | ||
media_library_item_details_frame_id_value: ::Avo::MEDIA_LIBRARY_ITEM_DETAILS_FRAME_ID, | ||
} do |c| %> | ||
<%= c.with_tools do %> | ||
<% if false && @attaching %> | ||
<%= a_button data: { | ||
action: 'click->media-library#selectItems', | ||
} do %> | ||
Attach | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
<% c.with_body do %> | ||
<% if !@attaching %> | ||
<%= content_tag :div, class: "p-4 pb-0", | ||
data: { | ||
controller: 'media-library-attach', | ||
media_library_attach_direct_uploads_url_value: helpers.main_app.rails_direct_uploads_url, | ||
} do %> | ||
<%= content_tag :div, | ||
class: 'dropzone relative py-6 text-center border-dashed border-2 border-gray-300 rounded-lg justify-center items-center flex flex-col text-gray-400 hover:border-primary-500 cursor-pointer', | ||
data: { | ||
media_library_attach_target: 'dropzone', | ||
action: 'click->media-library-attach#triggerFileBrowser', | ||
} do %> | ||
<%= helpers.svg 'heroicons/outline/cloud-arrow-up', class: 'size-6 text-gray-400' %> | ||
Upload a file | ||
<small>Click to browse or drag and drop</small> | ||
<% end %> | ||
|
||
<%= content_tag :div, "", class: "m-2 flex flex-wrap gap-2 empty:m-0", data: { | ||
media_library_attach_target: 'uploadingContainer', | ||
turbo_permanent: true, | ||
} %> | ||
<% end %> | ||
<% end %> | ||
<div class="grid grow-0 min-h-24 gap-x-4 @container/index" style="grid-template-areas: 'stack';"> | ||
<div class="grid grid-cols-1 @sm/index:grid-cols-2 @lg/index:grid-cols-3 @3xl/index:grid-cols-4 @5xl/index:grid-cols-6 gap-4 min-h-0 min-w-0 auto-rows-max p-4" style="grid-area: stack;"> | ||
<%= render Avo::MediaLibrary::ListItemComponent.with_collection(@blobs, attaching: @attaching, multiple: @attaching) %> | ||
</div> | ||
<%# TODO: fix the extra margin %> | ||
<%= helpers.turbo_frame_tag ::Avo::MEDIA_LIBRARY_ITEM_DETAILS_FRAME_ID, class: 'relative empty:hidden bg-white inset-0 w-full h-full block empty:-ml-4 max-h-full', style: 'grid-area: stack;' %> | ||
</div> | ||
<% end %> | ||
<% c.with_bare_content do %> | ||
<div class="flex-1 flex w-full mt-4"> | ||
<div class="flex-2 w-full sm:flex sm:items-center sm:justify-between space-y-2 sm:space-y-0 text-center sm:text-left pagy-gem-version-<%= helpers.pagy_major_version %> "> | ||
<div class="text-sm text-slate-600 mr-4"><%== helpers.pagy_info @pagy %></div> | ||
<% if @pagy.pages > 1 %> | ||
<%== helpers.pagy_nav(@pagy, xanchor_string: "data-turbo-frame=\"#{@turbo_frame}\"") %> | ||
<% end %> | ||
</div> | ||
</div> | ||
<% end %> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# frozen_string_literal: true | ||
|
||
module Avo | ||
module MediaLibrary | ||
class ListComponent < Avo::BaseComponent | ||
include Avo::ApplicationHelper | ||
include Pagy::Backend | ||
|
||
def initialize(attaching: false, turbo_frame: nil) | ||
@attaching = attaching | ||
@pagy, @blobs = pagy(query, limit:) | ||
turbo_frame ||= params[:turbo_frame] | ||
@turbo_frame = turbo_frame.present? ? CGI.escapeHTML(turbo_frame.to_s) : :_top | ||
end | ||
|
||
def controller = Avo::Current.view_context.controller | ||
|
||
def query | ||
ActiveStorage::Blob.includes(:attachments) | ||
# ignore blobs who are just a variant to avoid "n+1" blob creation | ||
.where.not(id: ActiveStorage::Attachment.where(record_type: "ActiveStorage::VariantRecord").pluck(:blob_id)) | ||
.order(created_at: :desc) | ||
end | ||
|
||
def limit = @attaching ? 12 : 24 | ||
end | ||
end | ||
end |
26 changes: 26 additions & 0 deletions
26
app/components/avo/media_library/list_item_component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<%= link_to helpers.avo.media_library_path(blob), | ||
id: dom_id(blob), | ||
class: "relative group min-h-full max-w-full flex-1 flex flex-col justify-between gap-2 border border-slate-200 p-1.5 rounded-xl hover:border-blue-500 hover:outline data-[selected=true]:border-blue-500 data-[selected=true]:outline outline-2 outline-blue-500", | ||
data: do %> | ||
<% if false && @attaching %> | ||
<div class="absolute bg-blue-500 group-hover:opacity-100 group-data-[selected=true]:opacity-100 opacity-0 inset-auto left-0 top-0 text-white rounded-tl-xl rounded-br-xl -ml-px -mt-px p-2"><div class="border border-white"><%= helpers.svg "heroicons/outline/check", class: 'group-data-[selected=true]:opacity-100 opacity-0 size-4' %></div></div> | ||
<% end %> | ||
<div class="flex flex-col h-full aspect-video overflow-hidden rounded-lg justify-center items-center"> | ||
<% if blob.image? %> | ||
<%= image_tag helpers.main_app.url_for(blob.variant(resize_to_limit: [600, 600])), class: "max-w-full self-start #{@extra_classes}", loading: :lazy, width: blob.metadata["width"], height: blob.metadata["height"] %> | ||
<% elsif blob.audio? %> | ||
<%= audio_tag(helpers.main_app.url_for(blob), controls: true, preload: false, class: 'w-full') %> | ||
<% elsif blob.video? %> | ||
<%= video_tag(helpers.main_app.url_for(blob), controls: true, preload: false, class: 'w-full') %> | ||
<% else %> | ||
<div class="relative h-full flex flex-col justify-center items-center w-full bg-slate-100"> | ||
<%= helpers.svg "heroicons/outline/document-text", class: 'h-10 text-gray-600 mb-2' %> | ||
</div> | ||
<% end %> | ||
</div> | ||
<div class="flex space-x-2 mb-1"> | ||
<% if @display_filename %> | ||
<span class="text-gray-500 group-hover:text-blue-700 mt-1 text-sm truncate" title="<%= blob.filename %>"><%= blob.filename %></span> | ||
<% end %> | ||
</div> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# frozen_string_literal: true | ||
|
||
module Avo | ||
module MediaLibrary | ||
class ListItemComponent < Avo::BaseComponent | ||
with_collection_parameter :blob | ||
|
||
prop :blob, reader: :public | ||
prop :display_filename, default: true | ||
prop :attaching, default: false | ||
prop :multiple, default: false | ||
|
||
def data | ||
{ | ||
component: component_name, | ||
blob_id: blob.id, | ||
media_library_blob_param: blob.as_json, | ||
media_library_path_param: helpers.main_app.url_for(blob), | ||
media_library_attaching_param: @attaching, | ||
media_library_multiple_param: @multiple, | ||
media_library_selected_item: params[:controller_selector], | ||
action: "click->media-library#selectItem" | ||
}.tap do |result| | ||
if @attaching | ||
result[:turbo_frame] = Avo::MEDIA_LIBRARY_ITEM_DETAILS_FRAME_ID | ||
result[:turbo_prefetch] = false | ||
else | ||
result[:turbo_prefetch] = true | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.