Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/admin.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/dark-theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/light-theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/builds/alchemy/theme.css

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions app/components/alchemy/admin/resource/select_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Alchemy
module Admin
module Resource
class SelectFilter < ViewComponent::Base
attr_reader :name, :resource_name, :label, :include_blank, :options, :selected
attr_reader :name, :resource_name, :label, :include_blank, :options, :selected, :multiple

erb_template <<~ERB
<div class="filter-input">
Expand All @@ -14,17 +14,19 @@ class SelectFilter < ViewComponent::Base
options_for_select(options, selected),
include_blank: include_blank,
form: "resource_search",
multiple: multiple,
is: 'alchemy-select'
) %>
</div>
ERB

def initialize(name:, resource_name:, label:, include_blank:, options:, params:)
def initialize(name:, resource_name:, label:, include_blank:, options:, params:, multiple: false)
@name = name
@options = options
@label = label
@include_blank = include_blank
@resource_name = resource_name
@multiple = multiple
@selected = get_selected_value_from(params)
end

Expand Down
49 changes: 42 additions & 7 deletions app/controllers/alchemy/admin/attachments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ class AttachmentsController < ResourcesController
include UploaderResponses
include ArchiveOverlay

add_alchemy_filter :by_file_type, type: :select,
options: -> { Alchemy::Attachment.file_types(_1.result) }
add_alchemy_filter :by_file_type, type: :select, options: ->(_query, params) do
case params&.to_h
in {except:}
Attachment.file_types - Attachment.file_types(from_extensions: except)
in {only:}
Attachment.file_types(from_extensions: only)
else
Attachment.file_types
end
end

add_alchemy_filter :recent, type: :checkbox
add_alchemy_filter :last_upload, type: :checkbox
add_alchemy_filter :without_tag, type: :checkbox
Expand Down Expand Up @@ -70,11 +79,37 @@ def destroy
private

def search_filter_params
@_search_filter_params ||= params.except(*COMMON_SEARCH_FILTER_EXCLUDES + [:attachment]).permit(
*common_search_filter_includes + [
:form_field_id
]
)
@_search_filter_params ||= begin
params[:q] ||= ActionController::Parameters.new

if params[:only].present?
params[:q][:by_file_type] ||= Array(params[:only]).map do |extension|
Marcel::MimeType.for(extension:)
end
end

if params[:except].present?
params[:q][:by_file_type] ||= Attachment.file_types - params[:except].map do |extension|
Marcel::MimeType.for(extension:)
end
end

params.except(*COMMON_SEARCH_FILTER_EXCLUDES + [:attachment]).permit(
*common_search_filter_includes + [
:form_field_id,
{only: []},
{except: []}
]
)
end
end

def permitted_ransack_search_fields
super + [
{by_file_type: []},
:not_file_type,
{not_file_type: []}
]
end

def handle_uploader_response(status:)
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/alchemy_admin/components/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Select extends HTMLSelectElement {
}

get allowClear() {
return this.dataset.hasOwnProperty("allowClear")
return this.dataset.hasOwnProperty("allowClear") || this.multiple
}
}

Expand Down
21 changes: 15 additions & 6 deletions app/models/alchemy/admin/filters/select.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,25 @@ def input_component(params, query)
name:,
resource_name:,
label: translated_name,
include_blank:,
options: get_options_for_select(query),
include_blank: include_blank(params),
options: get_options_for_select(query, params),
multiple: multiple?(params),
params:
)
end

private

def include_blank
Alchemy.t(:all, scope: [:filters, resource_name, name])
def multiple?(params)
params[:only].presence&.many? || params[:except].present?
end

def include_blank(params)
if params[:only].present? || params[:except].present?
false
else
Alchemy.t(:all, scope: [:filters, resource_name, name])
end
end

def options_to_proc(options)
Expand All @@ -44,8 +53,8 @@ def options_to_proc(options)
end
end

def get_options_for_select(query)
options_for_select = options.call(query)
def get_options_for_select(query, params = nil)
options_for_select = (options.arity == 1) ? options.call(query) : options.call(query, params)
# The result of the query is an Array of Arrays, where the first element is the translated name and the second element is the value.
# If the first element is an Array, we assume that the options are already translated.
if options_for_select.first.is_a? Array
Expand Down
15 changes: 12 additions & 3 deletions app/models/alchemy/attachment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ class Attachment < BaseRecord

stampable stamper_class_name: Alchemy.user_class_name

scope :by_file_type, ->(file_type) do
scope :by_file_type, ->(*file_type) do
Alchemy.storage_adapter.by_file_type_scope(file_type)
end

scope :not_file_type, ->(*file_type) do
Alchemy.storage_adapter.not_file_type_scope(file_type)
end

scope :recent, -> { where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at) }
scope :without_tag, -> { left_outer_joins(:taggings).where(gutentag_taggings: {id: nil}) }

Expand Down Expand Up @@ -70,7 +74,12 @@ def ransackable_associations(_auth_object = nil)
Alchemy.storage_adapter.ransackable_associations(name)
end

def file_types(scope = all)
def file_types(scope = all, from_extensions: nil)
if from_extensions.present?
scope = by_file_type(
Array(from_extensions).map { |extension| Marcel::MimeType.for(extension:) }
)
end
Alchemy.storage_adapter.file_formats(name, scope:)
end

Expand All @@ -79,7 +88,7 @@ def allowed_filetypes
end

def ransackable_scopes(_auth_object = nil)
%i[by_file_type recent last_upload without_tag deletable]
%i[by_file_type not_file_type recent last_upload without_tag deletable]
end
end

Expand Down
1 change: 1 addition & 0 deletions app/models/alchemy/storage_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class UnknownAdapterError < StandardError; end
:attachment_url_class,
:by_file_format_scope,
:by_file_type_scope,
:not_file_type_scope,
:file_extension,
:file_formats,
:file_mime_type,
Expand Down
10 changes: 8 additions & 2 deletions app/models/alchemy/storage_adapter/active_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,24 @@ def rescuable_errors
::ActiveStorage::Error
end

# @param [String]
# @param [String, Array<String>]
# @return [Alchemy::Picture::ActiveRecord_Relation]
def by_file_format_scope(file_format)
Picture.with_attached_image_file.joins(:image_file_blob).where(active_storage_blobs: {content_type: file_format})
end

# @param [String]
# @param [String, Array<String>]
# @return [Alchemy::Atachment::ActiveRecord_Relation]
def by_file_type_scope(file_type)
Attachment.with_attached_file.joins(:file_blob).where(active_storage_blobs: {content_type: file_type})
end

# @param [String, Array<String>]
# @return [Alchemy::Atachment::ActiveRecord_Relation]
def not_file_type_scope(file_type)
Attachment.with_attached_file.joins(:file_blob).where.not(active_storage_blobs: {content_type: file_type})
end

# @param [Alchemy::Attachment]
# @return [String]
def file_name(attachment)
Expand Down
10 changes: 8 additions & 2 deletions app/models/alchemy/storage_adapter/dragonfly.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,24 @@ def rescuable_errors
::Dragonfly::Job::Fetch::NotFound
end

# @param [String]
# @param [String, Array<String>]
# @return [Alchemy::Picture::ActiveRecord_Relation]
def by_file_format_scope(file_format)
Picture.where(image_file_format: file_format)
end

# @param [String]
# @param [String, Array<String>]
# @return [Alchemy::Attachment::ActiveRecord_Relation]
def by_file_type_scope(file_type)
Attachment.where(file_mime_type: file_type)
end

# @param [String, Array<String>]
# @return [Alchemy::Attachment::ActiveRecord_Relation]
def not_file_type_scope(file_type)
Attachment.where.not(file_mime_type: file_type)
end

# @param [Alchemy::Attachment]
# @return [String]
def file_name(attachment)
Expand Down
4 changes: 2 additions & 2 deletions app/stylesheets/alchemy/_themes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
--button-border-color: var(--color-blue_medium);
--button-box-shadow: 0 1px 1px -1px hsl(0deg, 0%, 10%);
--button-focus-border-color: var(--color-orange_dark);
--button-focus-box-shadow: 0 1px 1px 0 var(--button-focus-border-color);
--button-focus-box-shadow: 0 0 0 1px var(--button-focus-border-color);
--button-hover-bg-color: var(--color-blue_medium);
--button-hover-border-color: var(--color-blue_medium);
--button-text-color: var(--color-white);
Expand Down Expand Up @@ -293,7 +293,7 @@
--button-border-color: var(--border-color);
--button-box-shadow: 0 1px 1px -1px hsl(0deg, 0%, 20%);
--button-focus-border-color: var(--color-orange_dark);
--button-focus-box-shadow: 0 1px 1px 0 var(--button-focus-border-color);
--button-focus-box-shadow: 0 0 0 1px var(--button-focus-border-color);
--button-hover-bg-color: var(--color-grey_very_light);
--button-hover-border-color: hsla(0deg, 0%, 59%, 0.5);
--button-text-color: var(--text-color);
Expand Down
23 changes: 13 additions & 10 deletions app/stylesheets/alchemy/admin/archive.scss
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,11 @@ div#library_sidebar {
top: 0;
right: 0;
width: var(--sidebar-width);
overflow-y: auto;

padding: calc(var(--top-menu-height) + var(--spacing-2)) var(--spacing-4)
calc(var(--pagination-height) + var(--spacing-2)) var(--spacing-4);
height: 100%;
var(--spacing-2) var(--spacing-4);
height: calc(100% - var(--pagination-height));
z-index: 3;
background-color: var(--sidebar-background-color);

Expand All @@ -270,18 +271,14 @@ div#library_sidebar {
}

h3 {
margin: 1.5em 0 1em;
margin: var(--spacing-4) 0 var(--spacing-3) 0;
font-size: var(--font-size_medium);
}
}

.alchemy-dialog #library_sidebar {
position: absolute;
}

.alchemy-dialog-body {
#library_sidebar {
padding: 0 var(--spacing-4) var(--pagination-height);
}
padding: 0 var(--spacing-4);
}

#assign_image_list,
Expand All @@ -295,6 +292,10 @@ div#library_sidebar {
padding-bottom: 60px;
}

#assign_file_list {
padding-left: var(--spacing-1);
}

#overlay_picture_list {
height: 100%;
overflow: auto;
Expand All @@ -310,8 +311,10 @@ div#library_sidebar {

#overlay_file_list {
max-height: 100%;
overflow-x: visible;
overflow-y: auto;
padding-bottom: var(--pagination-height);
height: calc(100% - var(--pagination-height));
padding-left: var(--spacing-1);

.assign_file_file {
display: block;
Expand Down
4 changes: 2 additions & 2 deletions app/stylesheets/alchemy/admin/lists.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ ul.list {
overflow: hidden;
background-color: transparent;
font-weight: bold;
padding: var(--spacing-1) var(--spacing-2);
margin-bottom: var(--spacing-2);
padding: 0 var(--spacing-2);
margin: var(--spacing-1) 0 var(--spacing-2) 0;

.list-secondary {
color: var(--text-color);
Expand Down
1 change: 1 addition & 0 deletions app/stylesheets/alchemy/admin/selects.scss
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ select {
color: var(--form-field-text-color);
padding: 3px 6px;
margin: 0;
width: 0;

&.select2-active {
background: var(--form-field-background-color) !important;
Expand Down
6 changes: 1 addition & 5 deletions app/stylesheets/alchemy/admin/tags.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
.tag-list {
display: flex;
flex-direction: column;
min-height: 0;
padding-top: var(--spacing-4);
margin-bottom: var(--spacing-2);

label {
display: block;
Expand All @@ -29,9 +28,6 @@
list-style-type: none;
padding: 0;
margin: 0;
height: 100%;
overflow-x: hidden;
overflow-y: auto;

li {
display: block;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<% if @attachments.empty? %>
<%= render_message do %>
<% if search_filter_params[:q].present? %>
<% if search_filter_params.present? %>
<%= Alchemy.t(:no_search_results) %>
<% else %>
<%= Alchemy.t(:no_files_in_archive) %>
Expand Down
12 changes: 10 additions & 2 deletions app/views/alchemy/admin/partials/_remote_search_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
<%- url ||= url_for({ action: 'index' }.merge(
<%- clear_url ||= url_for({ action: 'index' }.merge(
q: search_filter_params[:q]&.except(resource_handler.search_field_name),
only: search_filter_params[:only],
except: search_filter_params[:except],
form_field_id: @form_field_id,
size: @size
)) -%>

<%= search_form_for @query, url: url_for(action: 'index', size: @size), remote: true, html: {class: 'search_form', id: "resource_search"} do |f| %>
<%= hidden_field_tag :form_field_id, @form_field_id %>
<% Array(params[:only]).each do |only| %>
<%= hidden_field_tag("only[]", only, form: "resource_search", id: nil) %>
<% end %>
<% Array(params[:except]).each do |except| %>
<%= hidden_field_tag("except[]", except, form: "resource_search", id: nil) %>
<% end %>
<div class="search_field">
<button type="submit">
<%= render_icon('search') %>
Expand All @@ -14,7 +22,7 @@
placeholder: Alchemy.t(:search),
class: 'search_input_field',
id: nil %>
<%= link_to render_icon(:times, size: '1x'), url,
<%= link_to render_icon(:times, size: '1x'), clear_url,
remote: true,
class: 'search_field_clear',
title: Alchemy.t(:click_to_show_all),
Expand Down
Loading
Loading