diff --git a/app/assets/stylesheets/alchemy/admin.scss b/app/assets/stylesheets/alchemy/admin.scss index 97be98ce9c..08f8544f43 100644 --- a/app/assets/stylesheets/alchemy/admin.scss +++ b/app/assets/stylesheets/alchemy/admin.scss @@ -29,6 +29,7 @@ @import "alchemy/image_library"; @import "alchemy/labels"; @import "alchemy/nodes"; +@import "alchemy/attachment-select"; @import "alchemy/node-select"; @import "alchemy/notices"; @import "alchemy/page-select"; diff --git a/app/assets/stylesheets/alchemy/attachment-select.scss b/app/assets/stylesheets/alchemy/attachment-select.scss new file mode 100644 index 0000000000..8c3bc9d645 --- /dev/null +++ b/app/assets/stylesheets/alchemy/attachment-select.scss @@ -0,0 +1,19 @@ +.attachment-select--attachment { + display: flex; + align-items: center; + height: 21px; + + .icon { + margin: 0 $default-margin 0 0; + + .select2-highlighted & { + fill: $white; + } + } +} + +.attachment-select--attachment-name { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} diff --git a/app/components/alchemy/admin/attachment_select.rb b/app/components/alchemy/admin/attachment_select.rb new file mode 100644 index 0000000000..0baa792882 --- /dev/null +++ b/app/components/alchemy/admin/attachment_select.rb @@ -0,0 +1,39 @@ +module Alchemy + module Admin + class AttachmentSelect < ViewComponent::Base + delegate :alchemy, to: :helpers + + def initialize(attachment = nil, url: nil, placeholder: Alchemy.t("Please choose"), query_params: nil) + @attachment = attachment + @url = url + @placeholder = placeholder + @query_params = query_params + end + + def call + content_tag("alchemy-attachment-select", content, attributes) + end + + private + + def attributes + options = { + "allow-clear": true, + placeholder: @placeholder, + url: @url || alchemy.api_attachments_path + } + + if @query_params + options[:"query-params"] = @query_params.to_json + end + + if @attachment + selection = ActiveModelSerializers::SerializableResource.new(@attachment) + options[:selection] = selection.to_json + end + + options + end + end + end +end diff --git a/app/components/alchemy/admin/link_dialog/file_tab.rb b/app/components/alchemy/admin/link_dialog/file_tab.rb index abd6cf12ba..a2abdb752f 100644 --- a/app/components/alchemy/admin/link_dialog/file_tab.rb +++ b/app/components/alchemy/admin/link_dialog/file_tab.rb @@ -28,18 +28,10 @@ def message private - def attachments - @_attachments ||= Attachment.all.collect { |f| - [f.name, alchemy.download_attachment_path(id: f.id, name: f.slug)] - } - end - def attachment_select label = label_tag("file_link", Alchemy.t(:file), class: "control-label") - select = select_tag "file_link", - options_for_select(attachments), - prompt: Alchemy.t("Please choose"), - is: "alchemy-select" + input = text_field_tag("file_link", "", id: "file_link") + select = render Alchemy::Admin::AttachmentSelect.new.with_content(input) content_tag("div", label + select, class: "input select") end end diff --git a/app/controllers/alchemy/api/attachments_controller.rb b/app/controllers/alchemy/api/attachments_controller.rb new file mode 100644 index 0000000000..ead20b735e --- /dev/null +++ b/app/controllers/alchemy/api/attachments_controller.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Alchemy + class Api::AttachmentsController < Api::BaseController + def index + authorize! :index, Attachment + + @attachments = Attachment.all + @attachments = @attachments.ransack(params[:q]).result + + if params[:page] + @attachments = @attachments.page(params[:page]).per(params[:per_page]) + end + + render json: @attachments, adapter: :json, root: "data", meta: meta_data + end + + private + + def meta_data + { + total_count: total_count_value, + per_page: per_page_value, + page: page_value + } + end + + def total_count_value + params[:page] ? @attachments.total_count : @attachments.size + end + + def per_page_value + if params[:page] + (params[:per_page] || Kaminari.config.default_per_page).to_i + else + @attachments.size + end + end + + def page_value + params[:page] ? params[:page].to_i : 1 + end + end +end diff --git a/app/javascript/alchemy_admin/components/attachment_select.js b/app/javascript/alchemy_admin/components/attachment_select.js new file mode 100644 index 0000000000..67672c1e88 --- /dev/null +++ b/app/javascript/alchemy_admin/components/attachment_select.js @@ -0,0 +1,24 @@ +import { RemoteSelect } from "alchemy_admin/components/remote_select" + +class AttachmentSelect extends RemoteSelect { + _renderResult(item) { + return this._renderListEntry(item) + } + + /** + * html template for each list entry + * @param {object} page + * @returns {string} + * @private + */ + _renderListEntry(attachment) { + return ` +
+ + ${attachment.name} +
+ ` + } +} + +customElements.define("alchemy-attachment-select", AttachmentSelect) diff --git a/app/javascript/alchemy_admin/components/index.js b/app/javascript/alchemy_admin/components/index.js index 4b9a1ad75e..ce99e625e0 100644 --- a/app/javascript/alchemy_admin/components/index.js +++ b/app/javascript/alchemy_admin/components/index.js @@ -1,3 +1,4 @@ +import "alchemy_admin/components/attachment_select" import "alchemy_admin/components/button" import "alchemy_admin/components/char_counter" import "alchemy_admin/components/clipboard_button" diff --git a/app/serializers/alchemy/attachment_serializer.rb b/app/serializers/alchemy/attachment_serializer.rb index 5249d34a24..36b039c018 100644 --- a/app/serializers/alchemy/attachment_serializer.rb +++ b/app/serializers/alchemy/attachment_serializer.rb @@ -7,6 +7,7 @@ class AttachmentSerializer < ActiveModel::Serializer :file_name, :file_mime_type, :file_size, + :icon_css_class, :tag_list, :created_at, :updated_at diff --git a/config/routes.rb b/config/routes.rb index 67915af451..56fce05faf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -115,6 +115,7 @@ resources :elements, only: :show namespace :api, defaults: {format: "json"} do + resources :attachments, only: [:index] resources :ingredients, only: [:index] resources :elements, only: [:index, :show]